diff --git a/.travis.yml b/.travis.yml index 641fa73d5e..481198eaa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -191,7 +191,7 @@ script: # - echo "$LD_LIBRARY_PATH" # - echo "$DYLD_FALLBACK_LIBRARY_PATH" - python3 -m helics - - python3 -m pytest -v ../tests/python_helics + - python3 -m pytest -sv ../tests/python_helics notifications: email: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a23f7664c..5742f2735e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,12 @@ All notable changes to this project after the 1.0.0 release will be documented i The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [unreleased] +## [1.0.2] -2018-04-28 +### Fixed + - Bug not allowing command line parameters separate from the command if a positional argument was in usage + - Fixed Bug for federate not allowing changes in period or minTimeDelay after entry to execution mode + - added python2 interface option (this will be available but not fully capable going forward) + - A few more race conditions fixed from clang thread-sanitizer ## [1.0.1] - 2018-04-22 ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index fcaab7b9a7..51442604a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ ############################################################################## -#Copyright © 2017-2018, +#Copyright © 2017-2018, #Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable Energy, LLC #All rights reserved. See LICENSE file and DISCLAIMER for more details. ############################################################################## @@ -12,9 +12,9 @@ project (HELICS) #----------------------------------------------------------------------------- set (HELICS_VERSION_MAJOR 1) set (HELICS_VERSION_MINOR 0) -set (HELICS_VERSION_PATCH 1) +set (HELICS_VERSION_PATCH 2) set (HELICS_VERSION_BUILD 0) -set (HELICS_DATE "04-22-18") +set (HELICS_DATE "04-28-18") set (HELICS_VERSION "${HELICS_VERSION_MAJOR}.${HELICS_VERSION_MINOR}.${HELICS_VERSION_PATCH}") set (HELICS_VERSION_STRING "${HELICS_VERSION} ${HELICS_DATE}") @@ -404,7 +404,7 @@ INSTALL(FILES ${KEY_LIBRARY_FILES} OPTION(ENABLE_CLANG_TOOLS "if clang is found enable some custom targets for clang formatting and tidy" OFF) if (ENABLE_CLANG_TOOLS) -include(clang-cxx-dev-tools) + include(clang-cxx-dev-tools) endif(ENABLE_CLANG_TOOLS) if (INTERFACE_BUILD) @@ -514,7 +514,9 @@ endif() # ------------------------------------------------------------- # CPack # ------------------------------------------------------------- +OPTION(ENABLE_PACKAGE_BUILD "Add projects for making packages and installers for HELICS" OFF) +IF(ENABLE_PACKAGE_BUILD) set(CPACK_PACKAGE_NAME "Helics") set(CPACK_PACKAGE_VENDOR "GMLC") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "HELICS") @@ -570,3 +572,4 @@ endif(WIN32) set(CPACK_SOURCE_IGNORE_FILES "/Build*/;/build*/;/.git/") #THIS LINE MUST BE LAST include(CPack) +ENDIF(ENABLE_PACKAGE_BUILD) \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 2ba3c4dfe5..646b06a4a1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ shallow_clone: true -version: 1.0.1.{build} +version: 1.0.2.{build} image: Visual Studio 2015 @@ -20,7 +20,7 @@ before_build: - IF NOT EXIST C:\ProgramData\chocolatey\bin\swig.exe choco install swig --yes --limit-output #> $null - mkdir build - cd build - - cmake .. -G "Visual Studio 14 2015 Win64" -DAUTOBUILD_ZMQ=ON -DBOOST_INSTALL_PATH=C:/libraries/boost_1_63_0 -DBUILD_RELEASE_ONLY=ON -DBUILD_C_SHARED_LIB=ON -DBUILD_JAVA_INTERFACE=ON -DBUILD_HELICS_EXAMPLES=ON + - cmake .. -G "Visual Studio 14 2015 Win64" -DAUTOBUILD_ZMQ=ON -DBOOST_INSTALL_PATH=C:/libraries/boost_1_63_0 -DENABLE_PACKAGE_BUILD=ON -DBUILD_RELEASE_ONLY=ON -DBUILD_C_SHARED_LIB=ON -DBUILD_JAVA_INTERFACE=ON -DBUILD_HELICS_EXAMPLES=ON - cd .. build: diff --git a/docs/apps/App.md b/docs/apps/App.md index 0412ad0741..328d0077c4 100644 --- a/docs/apps/App.md +++ b/docs/apps/App.md @@ -1,7 +1,7 @@ helics_app ======= -The helics apps executable is one of the HELICS apps available with the library +The HELICS apps executable is one of the HELICS apps available with the library Its purpose is to provide a common executable for running any of the other as typical syntax is as follows @@ -11,9 +11,9 @@ helics-app.exe possible apps are #### Echo -The [Echo](echo.md) app is a responsive app that will echo any message sent to its endpoints back to the orginal source with a specified delay +The [Echo](echo.md) app is a responsive app that will echo any message sent to its endpoints back to the original source with a specified delay -THis is useful for testing communication pathways and in combination with filters can be used to create some interesting situations +This is useful for testing communication pathways and in combination with filters can be used to create some interesting situations #### Player The [player](Player.md) app will generate signals through specified interfaces from prescribed data @@ -29,9 +29,9 @@ The additional purpose is used as a library object as the basis for additional d #### Source -The [Source](Source.md) app is a signal generator like the player execpt that is can generate signals from defined patterns including some random signals in value and timing, and other patterns like sine, square wave, ramps +The [Source](Source.md) app is a signal generator like the player except that is can generate signals from defined patterns including some random signals in value and timing, and other patterns like sine, square wave, ramps and others. Used much like the player in situations some test signals are needed. #### Broker -The [Broker](Broker.md) executes a broker like the stand alone Broker app. \ No newline at end of file +The [Broker](Broker.md) executes a broker like the stand alone Broker app. diff --git a/docs/apps/Broker.md b/docs/apps/Broker.md index ae543286ca..5066c37758 100644 --- a/docs/apps/Broker.md +++ b/docs/apps/Broker.md @@ -1,7 +1,7 @@ Broker ======= -Brokers function as intermediaries or roots in the HELICS hiearchy +Brokers function as intermediaries or roots in the HELICS hierarchy The Broker can be run through the helics_broker or via helics-app @@ -51,7 +51,7 @@ the player executable also takes an untagged argument of a file name for example helics_player player_file.txt --stop 5 ``` -Players support both delimited text files and json files some examples can be found in +Players support both delimited text files and JSON files some examples can be found in [Player configuation Examples](https://github.com/GMLC-TDC/HELICS-src/tree/master/tests/helics/apps/test_files) @@ -79,7 +79,7 @@ the optional third column specifies a type valid types are time specifications are typically numerical with optional units `5` or `"500 ms"` or `23.7us` if there is a space between the number and units it must be enclosed in quotes if no units are specified the time defaults to units specified via `--timeunits` or seconds if none were specified -valid units are "s", "ms","us","min", "day", "hr", "ns", "ps" the default precision in HELICS is ns so time specified in ps is not guaranteed to be precise +valid units are "s", "ms", "us", "min", "day", "hr", "ns", "ps" the default precision in HELICS is ns so time specified in ps is not guaranteed to be precise | identifier | type | Example | @@ -194,5 +194,5 @@ Example JSON } ``` -some configuration can also be done through JSON through elements of "stop","local","separator","timeunits" +some configuration can also be done through JSON through elements of "stop", "local", "separator", "timeunits" and file elements can be used to load up additional files diff --git a/docs/apps/Player.md b/docs/apps/Player.md index ebaa5fb47d..bf7f602219 100644 --- a/docs/apps/Player.md +++ b/docs/apps/Player.md @@ -53,7 +53,7 @@ the player executable also takes an untagged argument of a file name for example helics_player player_file.txt --stop 5 ``` -Players support both delimited text files and json files some examples can be found in +Players support both delimited text files and JSON files some examples can be found in [Player configuation Examples](https://github.com/GMLC-TDC/HELICS-src/tree/master/tests/helics/apps/test_files) @@ -81,7 +81,7 @@ the optional third column specifies a type valid types are time specifications are typically numerical with optional units `5` or `"500 ms"` or `23.7us` if there is a space between the number and units it must be enclosed in quotes if no units are specified the time defaults to units specified via `--timeunits` or seconds if none were specified -valid units are "s", "ms","us","min", "day", "hr", "ns", "ps" the default precision in HELICS is ns so time specified in ps is not guaranteed to be precise +valid units are "s", "ms", "us", "min", "day", "hr", "ns", "ps" the default precision in HELICS is ns so time specified in ps is not guaranteed to be precise | identifier | type | Example | diff --git a/docs/apps/Source.md b/docs/apps/Source.md index 5200504828..9bb4bd1a5f 100644 --- a/docs/apps/Source.md +++ b/docs/apps/Source.md @@ -1,10 +1,10 @@ Source ======= -The Source app generates signals for other federates, it functions similarly to the +The Source app generates signals for other federates, it functions similarly to the player but doesn't take a prescribed file instead it generates signals according to some -mathematical function, like sine, ramp, pulse, or random walk. -THis can be useful for sending probing signals or just testing responses of the federate to various stimuli. +mathematical function, like sine, ramp, pulse, or random walk. +This can be useful for sending probing signals or just testing responses of the federate to various stimuli. Command line arguments diff --git a/docs/apps/Tracer.md b/docs/apps/Tracer.md index 89354e861d..656385909e 100644 --- a/docs/apps/Tracer.md +++ b/docs/apps/Tracer.md @@ -61,7 +61,7 @@ the tracer executable also takes an untagged argument of a file name for example helics_app tracer tracer_file.txt --stop 5 ``` -Tracers support both delimited text files and json files some examples can be found in +Tracers support both delimited text files and JSON files some examples can be found in [Player configuation Examples](https://github.com/GMLC-TDC/HELICS-src/tree/master/tests/helics/apps/test_files) diff --git a/docs/installation/index.md b/docs/installation/index.md index abe48ddab8..2869286460 100644 --- a/docs/installation/index.md +++ b/docs/installation/index.md @@ -18,3 +18,39 @@ Lines that don’t start with `$` are typically showing the output of the previo linux ``` +The following are a few things that could be useful to know before starting out. + +Firstly, you can follow HELICS development on our [GitHub](https://github.com/GMLC-TDC/HELICS-src) page. +HELICS is open-source. The development team uses `git` for version control, and GitHub to host the code publically. +The latest HELICS will be on the `develop` branch. +Tagged releases occur on the `master` branch. +If you clone the HELICS-src repository, you will be placed in the `master` branch by default. +To switch to the `develop` branch, you can type the following: + +```bash +git checkout develop +``` + +To switch to a tagged release, you can type the following: + +```bash +git checkout v1.0.1 +``` + +You will not need a full understanding of how `git` works for installing HELICS, but if you are interested you can find a good `git` resource in [this page](https://git-scm.com/book/en/v2). + +Secondly, HELICS-src is a modern CPP cross-platform software application. +One challenge while maintaining the same codebase across multiple operating systems is that we have to ensure that everything installs correctly everywhere. +The development team uses `CMake` to build HELICS. +`CMake` is a cross-platform tool designed to build, test and package software. +Having the latest version of `CMake` can make the build process much smoother. +`CMake` reads certain files (CMakeLists.txt) from the HELICS-src repository, and creates a bunch of build files. +These build files specify how different files depend on each other and when these build files are run, HELICS is built. +The exact instructions to run on each operating system are given in the individual installation instructions, but one important thing to remember is that these build files are essentially temporary files. +If you have an issue building HELICS, once you make a change (installing/removing/adding anything), you probably need to delete these temporary files and re-generate them. +We've found in practice that you don't have to do this too often, but it can save hours of frustration if you are already aware that this needs to be done. + +Another valuable piece of information about `CMake` is that almost every "OPTION" is configurable while you generate the build files. +This means you can pass it configurations settings as a key value pair by adding `-D{NAME_OF_OPTION}={VALUE_OF_OPTION}` to the `cmake` command line interface. +For example, to build the Python extension all you need to do is pass in `-DBUILD_PYTHON_INTERFACE=ON`. +Again, there are more instructions in the individual installation pages but a useful trick to know if something isn't documented or a slightly more advanced feature is required. diff --git a/docs/installation/linux.md b/docs/installation/linux.md index 78c646c340..46eae59ce2 100644 --- a/docs/installation/linux.md +++ b/docs/installation/linux.md @@ -82,7 +82,7 @@ IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: import helics In [2]: helics.helicsGetVersion() -Out[2]: '1.0.0-alpha.3 (02-12-18)' +Out[2]: '1.0.2 (04-28-18)' ``` diff --git a/docs/installation/mac.md b/docs/installation/mac.md index 4b7e4d15bc..217741afd2 100644 --- a/docs/installation/mac.md +++ b/docs/installation/mac.md @@ -124,10 +124,10 @@ recorder: cd /path/to/helics_install/bin $ helics_player --version -0.1 +1.0.2 (04-28-18) $ helics_recorder --version -0.1 +1.0.2 (04-28-18) ``` Building HELICS with python support @@ -159,7 +159,7 @@ IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: import helics In [2]: helics.helicsGetVersion() -Out[2]: '1.0.0-alpha.3 (02-12-18)' +Out[2]: '1.0.2 (04-28-18)' ``` diff --git a/docs/installation/windows.md b/docs/installation/windows.md index a19a447cbe..abc9a7cee8 100644 --- a/docs/installation/windows.md +++ b/docs/installation/windows.md @@ -23,11 +23,11 @@ To set up your environment: 1.61 or later recommended (core library should build with 1.58, but tests will not). For CMake to detect it automatically either extract Boost to the root of your drive, or set the BOOST\_INSTALL\_PATH - environment variable to the install location. The cmake will only automatically find - boost 1.61 or newer. + environment variable to the install location. The cmake will only automatically find + boost 1.61 or newer. Building with Visual Studio 2017 will require boost 1.65.1 or newer and cmake 3.9 or newer. Use 14.0 versions for Visual Studio 2015, 14.1 files for Visual studio 2017. - Boost 1.66 with cmake 3.11 is the current recommended configuration. + Boost 1.66 with cmake 3.11 is the current recommended configuration. 3. *Optional* Install [ZeroMQ](http://zeromq.org/build:_start) if you need ZeroMQ support and need a copy in a global system location. We recommend skipping this step and running cmake with the @@ -39,7 +39,7 @@ To set up your environment: if you need MPI support. 5. *Optional* Install [SWIG](http://www.swig.org/download.html) - if you wish to generate the interface libraries, appropriate build files are + if you wish to generate the interface libraries, appropriate build files are included in the repository so it shouldn't be necessary to regenerate unless the libraries are modified 6. Open a Visual Studio Command Prompt, and go to your working directory. @@ -106,18 +106,21 @@ recorder (located in the 'build\src\helics\apps\player\Debug' folder): > cd C:\Path\To\build\src\helics\apps\Debug > helics_player.exe --version -0.1 +1.0.2 04-28-2018 > helics_recorder.exe --version -0.1 +1.0.2 04-28-2018 ``` Building HELICS with python support ----------------------------------- -setting `-DBUILD_PYTHON_INTERFACE=ON` will generate a project to build the python interface, if python is installed to a system +Setting `-DBUILD_PYTHON_INTERFACE=ON` will generate a project to build the python interface, if python is installed to a system path then the appropriate libraries and flags will be automatically found. If SWIG is available and you wish to regenerate the interface set SWIG\_EXECUTABLE to the location of swig.exe. Otherwise DISABLE\_SWIG can be set to ON to build using repo sources for the interface. +We highly recommend using Anaconda3/Miniconda3 for the Python distribution. +Additionally, you will need to ensure that the Python distribution used is built using the same compiler architecture (x86/x64) as the one you are using to build HELICS, as well as the one that was used to build Boost (as mentioned above). +ZeroMQ will be built using the CMake build process. ![](../img/windows-command-line-install.png) @@ -137,7 +140,7 @@ cmake --build . --config Release --target install Add the following to the Windows PYTHONPATH environment variable or run the following in the command line. ```bash -set PYTHONPATH=C:\local\helics-v1.0.0\python;%PYTHONPATH% +set PYTHONPATH=C:\local\helics-v1.0.2\python;%PYTHONPATH% ``` If you open a interactive Python session and import helics, you should be able to get the version of `helics` and an output that is similar to the following. @@ -151,9 +154,8 @@ IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: import helics In [2]: helics.helicsGetVersion() -Out[2]: '1.0.0 (04-15-18)' +Out[2]: '1.0.2 (04-28-18)' ``` ![](../img/windows-python-success.png) - diff --git a/docs/introduction/java.md b/docs/introduction/java.md index 457dbee0e0..ed64f0cd5b 100644 --- a/docs/introduction/java.md +++ b/docs/introduction/java.md @@ -28,7 +28,7 @@ java -Djava.library.path="/Library/Java/Extensions:/Network/Library/Java/Extensi You should see the output that is similar to the following. ``` -HELICS Version: 1.0.0-beta.1 02-26-18 +HELICS Version: 1.0.2 (04-28-18) ``` creating a jar file. diff --git a/docs/mainpage.dox b/docs/mainpage.dox index 0bab1437c3..8497399884 100644 --- a/docs/mainpage.dox +++ b/docs/mainpage.dox @@ -2,7 +2,7 @@ @mainpage HELICS @image html HELICS_Logo.png width=5cm -

HELICS (Hiearchical Engine for Large-scale infrastructre Co-Simulation) is a co-simulation plaform +

HELICS (Hierarchical Engine for Large-Scale infrastructure Co-Simulation) is a co-simulation platform


@@ -11,4 +11,4 @@ [Disclaimer](../../DISCLAIMER)
[license](../../LICENSE) - */ \ No newline at end of file + */ diff --git a/src/helics/application_api/Endpoints.cpp b/src/helics/application_api/Endpoints.cpp index c869881f73..dc041797a8 100644 --- a/src/helics/application_api/Endpoints.cpp +++ b/src/helics/application_api/Endpoints.cpp @@ -1,5 +1,4 @@ /* - Copyright © 2017-2018, Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable Energy, LLC All rights reserved. See LICENSE file and DISCLAIMER for more details. diff --git a/src/helics/application_api/Federate.cpp b/src/helics/application_api/Federate.cpp index 9159990972..451bf47d95 100644 --- a/src/helics/application_api/Federate.cpp +++ b/src/helics/application_api/Federate.cpp @@ -543,10 +543,11 @@ iteration_time Federate::requestTimeIterative (Time nextInternalTimeStep, iterat void Federate::requestTimeAsync (Time nextInternalTimeStep) { - auto asyncInfo = asyncCallInfo->lock(); + auto exp = op_states::execution; if (state.compare_exchange_strong(exp,op_states::pending_time)) { + auto asyncInfo = asyncCallInfo->lock(); asyncInfo->timeRequestFuture = std::async (std::launch::async, [this, nextInternalTimeStep]() { return coreObject->timeRequest (fedID, nextInternalTimeStep); }); @@ -562,10 +563,11 @@ void Federate::requestTimeAsync (Time nextInternalTimeStep) @return the granted time step*/ void Federate::requestTimeIterativeAsync (Time nextInternalTimeStep, iteration_request iterate) { - auto asyncInfo = asyncCallInfo->lock(); + auto exp = op_states::execution; if (state.compare_exchange_strong(exp, op_states::pending_iterative_time)) { + auto asyncInfo = asyncCallInfo->lock(); asyncInfo->timeRequestIterativeFuture = std::async (std::launch::async, [this, nextInternalTimeStep, iterate]() { return coreObject->requestTimeIterative (fedID, nextInternalTimeStep, iterate); @@ -582,11 +584,14 @@ void Federate::requestTimeIterativeAsync (Time nextInternalTimeStep, iteration_r @return the granted time step*/ Time Federate::requestTimeComplete () { - auto asyncInfo = asyncCallInfo->lock(); + auto exp = op_states::pending_time; if (state.compare_exchange_strong(exp, op_states::execution)) { + + auto asyncInfo = asyncCallInfo->lock(); auto newTime = asyncInfo->timeRequestFuture.get (); + asyncInfo = nullptr; //remove the lock; Time oldTime = currentTime; currentTime = newTime; updateTime (newTime, oldTime); diff --git a/src/helics/apps/Echo.cpp b/src/helics/apps/Echo.cpp index c7b0425da8..7f260faf8b 100644 --- a/src/helics/apps/Echo.cpp +++ b/src/helics/apps/Echo.cpp @@ -23,12 +23,15 @@ static const ArgDescriptors InfoArgs{{"delay", "the delay with which the echo ap Echo::Echo (int argc, char *argv[]) : App ("echo", argc, argv) { - variable_map vm_map; - argumentParser (argc, argv, vm_map, InfoArgs); - loadArguments (vm_map); - if (!masterFileName.empty ()) + if (!deactivated) { - loadFile (masterFileName); + variable_map vm_map; + argumentParser(argc, argv, vm_map, InfoArgs); + loadArguments(vm_map); + if (!masterFileName.empty()) + { + loadFile(masterFileName); + } } } diff --git a/src/helics/apps/Player.cpp b/src/helics/apps/Player.cpp index d822faf120..cc84ee5ead 100644 --- a/src/helics/apps/Player.cpp +++ b/src/helics/apps/Player.cpp @@ -50,14 +50,18 @@ static const ArgDescriptors InfoArgs{ Player::Player (int argc, char *argv[]):App("player",argc,argv) { - fed->setFlag (SOURCE_ONLY_FLAG); - variable_map vm_map; - argumentParser(argc, argv, vm_map, InfoArgs); - loadArguments(vm_map); - if (!masterFileName.empty()) + if (!deactivated) { - loadFile(masterFileName); + fed->setFlag(SOURCE_ONLY_FLAG); + variable_map vm_map; + argumentParser(argc, argv, vm_map, InfoArgs); + loadArguments(vm_map); + if (!masterFileName.empty()) + { + loadFile(masterFileName); + } } + } Player::Player (const FederateInfo &fi) : App(fi) diff --git a/src/helics/apps/Recorder.cpp b/src/helics/apps/Recorder.cpp index ea18dd299e..b3796f23b1 100644 --- a/src/helics/apps/Recorder.cpp +++ b/src/helics/apps/Recorder.cpp @@ -49,14 +49,18 @@ static const ArgDescriptors InfoArgs{ Recorder::Recorder (int argc, char *argv[]):App("recorder",argc,argv) { - fed->setFlag (OBSERVER_FLAG); - variable_map vm_map; - argumentParser(argc, argv, vm_map, InfoArgs); - loadArguments(vm_map); - if (!masterFileName.empty()) + if (!deactivated) { - loadFile(masterFileName); + fed->setFlag(OBSERVER_FLAG); + variable_map vm_map; + argumentParser(argc, argv, vm_map, InfoArgs); + loadArguments(vm_map); + if (!masterFileName.empty()) + { + loadFile(masterFileName); + } } + } Recorder::Recorder (const std::shared_ptr &core, const FederateInfo &fi):App(core,fi) diff --git a/src/helics/apps/Source.cpp b/src/helics/apps/Source.cpp index a763c35791..f97c908cee 100644 --- a/src/helics/apps/Source.cpp +++ b/src/helics/apps/Source.cpp @@ -45,13 +45,16 @@ static const ArgDescriptors InfoArgs{ Source::Source (int argc, char *argv[]):App("source",argc,argv) { - fed->setFlag(SOURCE_ONLY_FLAG); - variable_map vm_map; - argumentParser(argc, argv, vm_map, InfoArgs, "input"s); - loadArguments(vm_map); - if (!masterFileName.empty()) + if (!deactivated) { - loadFile(masterFileName); + fed->setFlag(SOURCE_ONLY_FLAG); + variable_map vm_map; + argumentParser(argc, argv, vm_map, InfoArgs, "input"s); + loadArguments(vm_map); + if (!masterFileName.empty()) + { + loadFile(masterFileName); + } } } diff --git a/src/helics/apps/Tracer.cpp b/src/helics/apps/Tracer.cpp index 7c5d894981..3debf9d164 100644 --- a/src/helics/apps/Tracer.cpp +++ b/src/helics/apps/Tracer.cpp @@ -50,13 +50,16 @@ static const ArgDescriptors InfoArgs{ Tracer::Tracer(int argc, char *argv[]):App("tracer",argc,argv) { - fed->setFlag(OBSERVER_FLAG); - variable_map vm_map; - argumentParser(argc, argv, vm_map, InfoArgs); - loadArguments(vm_map); - if (!masterFileName.empty()) + if (!deactivated) { - loadFile(masterFileName); + fed->setFlag(OBSERVER_FLAG); + variable_map vm_map; + argumentParser(argc, argv, vm_map, InfoArgs); + loadArguments(vm_map); + if (!masterFileName.empty()) + { + loadFile(masterFileName); + } } } diff --git a/src/helics/apps/appMain.cpp b/src/helics/apps/appMain.cpp index 1ee92d9f8c..8dab18515f 100644 --- a/src/helics/apps/appMain.cpp +++ b/src/helics/apps/appMain.cpp @@ -8,10 +8,12 @@ All rights reserved. See LICENSE file and DISCLAIMER for more details. #include "Recorder.hpp" #include "Echo.hpp" #include "Tracer.hpp" +#include "Source.hpp" #include "../core/BrokerFactory.hpp" #include "../core/core-exceptions.hpp" #include "../core/helicsVersion.hpp" #include +#include void showHelp() { @@ -26,6 +28,7 @@ int main (int argc, char *argv[]) if (argc == 1) { showHelp(); + return 0; } std::string arg1(argv[1]); //now redo the arguments remove the second argument which is the app name @@ -36,7 +39,7 @@ int main (int argc, char *argv[]) } try { - if (arg1 == "player") + if (boost::iequals(arg1,"player")) { helics::apps::Player Player(argc, argv); if (Player.isActive()) @@ -45,7 +48,7 @@ int main (int argc, char *argv[]) } } - else if (arg1 == "recorder") + else if (boost::iequals(arg1, "recorder")) { helics::apps::Recorder Recorder(argc, argv); if (Recorder.isActive()) @@ -62,7 +65,7 @@ int main (int argc, char *argv[]) { showHelp(); } - else if (arg1 == "echo") + else if (boost::iequals(arg1, "echo")) { helics::apps::Echo Echo(argc, argv); if (Echo.isActive()) @@ -70,15 +73,19 @@ int main (int argc, char *argv[]) Echo.run(); } } - else if (arg1 == "source") + else if (boost::iequals(arg1, "source")) { - + helics::apps::Source Source(argc, argv); + if (Source.isActive()) + { + Source.run(); + } } - else if (arg1 == "broker") + else if (boost::iequals(arg1, "broker")) { } - else if (arg1 == "tracer") + else if (boost::iequals(arg1, "tracer")) { helics::apps::Tracer Tracer(argc, argv); if (Tracer.isActive()) diff --git a/src/helics/apps/helicsApp.cpp b/src/helics/apps/helicsApp.cpp index a61ea30289..7704e216db 100644 --- a/src/helics/apps/helicsApp.cpp +++ b/src/helics/apps/helicsApp.cpp @@ -37,24 +37,46 @@ namespace helics namespace apps { -static const ArgDescriptors InfoArgs{ +static const ArgDescriptors basicAppArgs{ {"local", ArgDescriptor::arg_type_t::flag_type, "specify otherwise unspecified endpoints and publications as local( i.e.the keys will be prepended with the player name"}, - {"stop", "the time to stop the player"} + {"stop", "the time to stop the player"}, + {"quiet", ArgDescriptor::arg_type_t::flag_type, "turn off most display output"} }; App::App (const std::string &appName,int argc, char *argv[]) { variable_map vm_map; - auto res = argumentParser(argc, argv, vm_map, InfoArgs,"input"); + //check for quiet mode + for (int ii = 0; ii < argc; ++ii) + { + if (argv[ii] != nullptr) + { + if (strcmp(argv[ii], "--quiet") == 0) + { + quietMode = true; + } + } + } + auto res = argumentParser(argc, argv, vm_map, basicAppArgs,"input"); + if (vm_map.count("quiet") > 0) + { + quietMode = true; + } if (res == versionReturn) { - std::cout << helics::versionString<< '\n'; + if (!quietMode) + { + std::cout << helics::versionString << '\n'; + } } if (res == helpReturn) { - FederateInfo helpTemp(argc, argv); + if (!quietMode) + { + FederateInfo helpTemp(argc, argv); + } } - if (res < 0) + if (res != 0) { deactivated = true; return; diff --git a/src/helics/apps/helicsApp.hpp b/src/helics/apps/helicsApp.hpp index 6761492a49..f0e8fccc0a 100644 --- a/src/helics/apps/helicsApp.hpp +++ b/src/helics/apps/helicsApp.hpp @@ -108,6 +108,7 @@ class App bool useLocal = false; bool fileLoaded = false; bool deactivated = false; + bool quietMode = false; }; } // namespace apps } // namespace helics diff --git a/src/helics/common/AsioServiceManager.h b/src/helics/common/AsioServiceManager.h index d109b597df..10ff5a98b7 100644 --- a/src/helics/common/AsioServiceManager.h +++ b/src/helics/common/AsioServiceManager.h @@ -16,8 +16,7 @@ All rights reserved. See LICENSE file and DISCLAIMER for more details. * LLNS Copyright End */ -#ifndef ASIO_SERVICE_MANAGER_HEADER_ -#define ASIO_SERVICE_MANAGER_HEADER_ +#pragma once #include #include @@ -123,5 +122,4 @@ class AsioServiceManager void serviceProcessingLoop(std::shared_ptr ptr); -#endif diff --git a/src/helics/common/argParser.cpp b/src/helics/common/argParser.cpp index 26bbca08ec..6e46f58452 100644 --- a/src/helics/common/argParser.cpp +++ b/src/helics/common/argParser.cpp @@ -74,6 +74,7 @@ int argumentParser (int argc, if (!posName.empty ()) { hidden.add_options () (posName.c_str (), po::value (), "positional argument"); + hidden.add_options() ("extra_positional_arguments", po::value>(), "unknown positional argument"); cmd_line.add (hidden); config_file.add (hidden); } @@ -98,7 +99,8 @@ int argumentParser (int argc, else { po::positional_options_description p; - p.add (posName.c_str (), -1); + p.add (posName.c_str (), 1); + p.add("extra_positional_arguments", 20); po::command_line_parser parser{argc, argv}; parser.options (cmd_line).allow_unregistered ().positional (p); parser.style (xstyle); @@ -118,7 +120,10 @@ int argumentParser (int argc, // program options control if (cmd_vm.count ("help") > 0) { - std::cout << visible << '\n'; + if (cmd_vm.count("quiet") == 0) + { + std::cout << visible << '\n'; + } return helpReturn; } if (cmd_vm.count ("version") > 0) @@ -134,7 +139,8 @@ int argumentParser (int argc, else { po::positional_options_description p; - p.add (posName.c_str (), -1); + p.add (posName.c_str (), 1); + p.add("extra_positional_arguments", 20); po::store (po::command_line_parser (argc, argv) .options (cmd_line) .allow_unregistered () diff --git a/src/helics/core/BrokerBase.cpp b/src/helics/core/BrokerBase.cpp index a2ea21013a..bba63e7bbf 100644 --- a/src/helics/core/BrokerBase.cpp +++ b/src/helics/core/BrokerBase.cpp @@ -9,6 +9,7 @@ All rights reserved. See LICENSE file and DISCLAIMER for more details. #include "../common/AsioServiceManager.h" #include "../common/argParser.h" #include "../common/logger.h" + #include "ForwardingTimeCoordinator.hpp" #include "helics/helics-config.h" #include "helicsVersion.hpp" @@ -252,12 +253,36 @@ void BrokerBase::addActionMessage (ActionMessage &&m) } } -using activeProtector = std::shared_ptr>; -void timerTickHandler (BrokerBase *bbase, activeProtector active, const boost::system::error_code &error) +using activeProtector = libguarded::guarded>; + +static void haltTimer(activeProtector &active, boost::asio::steady_timer &tickTimer) +{ + bool TimerRunning = true; + { + auto p = active.lock(); + if (p->second) + { + p->first = false; + tickTimer.cancel(); + } + else + { + TimerRunning = false; + } + } + while (TimerRunning) + { + std::this_thread::yield(); + auto res = active.load(); + TimerRunning = res.second; + } +} + +static void timerTickHandler (BrokerBase *bbase, activeProtector &active, const boost::system::error_code &error) { - auto p = active->lock (); - if (*p) + auto p = active.lock (); + if (p->first) { if (error != boost::asio::error::operation_aborted) { @@ -268,7 +293,7 @@ void timerTickHandler (BrokerBase *bbase, activeProtector active, const boost::s catch (std::exception &e) { std::cout << "exception caught from addActionMessage" << std::endl; - } + } } else { @@ -277,6 +302,7 @@ void timerTickHandler (BrokerBase *bbase, activeProtector active, const boost::s bbase->addActionMessage (M); } } + p->second = false; } bool BrokerBase::tryReconnect () { return false; } @@ -288,12 +314,13 @@ void BrokerBase::queueProcessingLoop () auto serv = AsioServiceManager::getServicePointer (); auto serviceLoop = AsioServiceManager::runServiceLoop (); boost::asio::steady_timer ticktimer (serv->getBaseService ()); - auto active = std::make_shared> (true); + activeProtector active(true,false); - auto timerCallback = [this, active](const boost::system::error_code &ec) { + auto timerCallback = [this, &active](const boost::system::error_code &ec) { timerTickHandler (this, active, ec); }; ticktimer.expires_at (std::chrono::steady_clock::now () + std::chrono::milliseconds (tickTimer)); + active = std::make_pair(true, true); ticktimer.async_wait (timerCallback); int messagesSinceLastTick = 0; auto logDump = [&, this]() { @@ -331,29 +358,27 @@ void BrokerBase::queueProcessingLoop () messagesSinceLastTick = 0; // reschedule the timer ticktimer.expires_at (std::chrono::steady_clock::now () + std::chrono::milliseconds (tickTimer)); + active = std::make_pair(true, true); ticktimer.async_wait (timerCallback); break; case CMD_IGNORE: break; case CMD_TERMINATE_IMMEDIATELY: - active->store(false); - ticktimer.cancel (); + haltTimer(active, ticktimer); serviceLoop = nullptr; - mainLoopIsRunning.store (false); - logDump (); + mainLoopIsRunning.store(false); + logDump(); return; // immediate return case CMD_STOP: - active->store(false); - ticktimer.cancel (); + haltTimer(active, ticktimer); serviceLoop = nullptr; if (!haltOperations) { processCommand (std::move (command)); mainLoopIsRunning.store (false); logDump (); - return processDisconnect (); + processDisconnect (); } - return; default: if (!haltOperations) diff --git a/src/helics/core/CommonCore.cpp b/src/helics/core/CommonCore.cpp index 7baf84aec1..565e5ed178 100644 --- a/src/helics/core/CommonCore.cpp +++ b/src/helics/core/CommonCore.cpp @@ -2400,12 +2400,17 @@ void CommonCore::processCommand (ActionMessage &&command) { if (command.dest_id == global_broker_id) { - auto filtI = filters.find (fed_handle_pair (global_broker_id, command.dest_handle)); - if (filtI != nullptr) - { - filtI->target = {command.source_id, command.source_handle}; - timeCoord->addDependency (command.source_id); + helics::FilterInfo *filtI = nullptr; + { //scope for the lock_guard + std::lock_guard lock(_handlemutex); + filtI = filters.find(fed_handle_pair(global_broker_id, command.dest_handle)); + if (filtI != nullptr) + { + filtI->target = { command.source_id, command.source_handle }; + timeCoord->addDependency(command.source_id); + } } + auto filthandle = getHandleInfo (command.dest_handle); if (filthandle != nullptr) { diff --git a/src/helics/core/CommsBroker.hpp b/src/helics/core/CommsBroker.hpp index 3a9b4f4886..c65055a208 100644 --- a/src/helics/core/CommsBroker.hpp +++ b/src/helics/core/CommsBroker.hpp @@ -38,7 +38,8 @@ class CommsBroker : public BrokerT private: virtual void brokerDisconnect () override; virtual bool tryReconnect () override; - + /** disconnect the comm object*/ + void commDisconnect(); public: virtual void transmit (int route_id, const ActionMessage &cmd) override; diff --git a/src/helics/core/CommsBroker_impl.hpp b/src/helics/core/CommsBroker_impl.hpp index 104253d36e..0fadd00f5e 100644 --- a/src/helics/core/CommsBroker_impl.hpp +++ b/src/helics/core/CommsBroker_impl.hpp @@ -43,7 +43,7 @@ CommsBroker::~CommsBroker () if (exp == 0) { lock.unlock (); - brokerDisconnect (); + commDisconnect (); lock.lock (); exp = 1; } @@ -61,15 +61,21 @@ CommsBroker::~CommsBroker () template void CommsBroker::brokerDisconnect () { - std::unique_lock lock (dataMutex); + commDisconnect(); +} + +template +void CommsBroker::commDisconnect() +{ + std::unique_lock lock(dataMutex); if (comms) { int exp = 0; - if (disconnectionStage.compare_exchange_strong (exp, 1)) + if (disconnectionStage.compare_exchange_strong(exp, 1)) { - auto comm_ptr = comms.get (); - lock.unlock (); // we don't want to hold the lock while calling disconnect that could cause deadlock - comm_ptr->disconnect (); + auto comm_ptr = comms.get(); + lock.unlock(); // we don't want to hold the lock while calling disconnect that could cause deadlock + comm_ptr->disconnect(); disconnectionStage = 2; } } diff --git a/src/helics/core/CoreBroker.cpp b/src/helics/core/CoreBroker.cpp index 23307423c2..9886ba15b9 100644 --- a/src/helics/core/CoreBroker.cpp +++ b/src/helics/core/CoreBroker.cpp @@ -994,7 +994,7 @@ bool CoreBroker::connect () bool CoreBroker::isConnected () const { return ((brokerState == operating) || (brokerState == connected)); } void CoreBroker::processDisconnect (bool skipUnregister) -{ +{ LOG_NORMAL (0, getIdentifier (), "||disconnecting"); if (brokerState > broker_state_t::initialized) { diff --git a/src/helics/core/FederateState.cpp b/src/helics/core/FederateState.cpp index a4b43bcec1..4a0317f878 100644 --- a/src/helics/core/FederateState.cpp +++ b/src/helics/core/FederateState.cpp @@ -437,8 +437,7 @@ iteration_result FederateState::enterExecutingState (iteration_request iterate) } addAction (exec); - ActionMessage execReq (CMD_EXEC_CHECK); - queue.emplace (execReq); + auto ret = processQueue (); if (ret == iteration_state::next_step) { @@ -523,7 +522,6 @@ iteration_time FederateState::requestTime (Time nextTime, iteration_request iter addAction (treq); LOG_TRACE (timeCoord->printTimeStatus ()); // timeCoord->timeRequest (nextTime, iterate, nextValueTime (), nextMessageTime ()); - queue.push (CMD_TIME_CHECK); auto ret = processQueue (); time_granted = timeCoord->getGrantedTime (); @@ -765,35 +763,13 @@ iteration_state FederateState::processActionMessage (ActionMessage &cmd) { if (state == HELICS_INITIALIZING) { - auto grant = timeCoord->checkExecEntry (); - switch (grant) - { - case iteration_state::iterating: - timeGranted_mode = true; - return grant; - case iteration_state::next_step: - setState (HELICS_EXECUTING); - LOG_DEBUG ("Granting Execution"); - timeGranted_mode = true; - return grant; - case iteration_state::continue_processing: - break; - default: - timeGranted_mode = true; - return grant; - } + cmd.setAction(CMD_EXEC_CHECK); + return processActionMessage(cmd); } else if (state == HELICS_EXECUTING) { - auto ret = timeCoord->checkTimeGrant (); - if (ret != iteration_state::continue_processing) - { - time_granted = timeCoord->getGrantedTime (); - allowed_send_time = timeCoord->allowedSendTime (); - LOG_DEBUG (std::string ("Granted Time=") + std::to_string (time_granted)); - timeGranted_mode = true; - return ret; - } + cmd.setAction(CMD_TIME_CHECK); + return processActionMessage(cmd); } } } @@ -819,7 +795,13 @@ iteration_state FederateState::processActionMessage (ActionMessage &cmd) } timeCoord->enteringExecMode (iterate); timeGranted_mode = false; - return processDelayQueue (); + auto ret = processDelayQueue(); + if (ret != iteration_state::continue_processing) + { + return ret; + } + cmd.setAction(CMD_EXEC_CHECK); + return processActionMessage(cmd); } FALLTHROUGH case CMD_EXEC_GRANT: @@ -924,7 +906,13 @@ iteration_state FederateState::processActionMessage (ActionMessage &cmd) } timeCoord->timeRequest (cmd.actionTime, iterate, nextValueTime (), nextMessageTime ()); timeGranted_mode = false; - return processDelayQueue (); + auto ret=processDelayQueue (); + if (ret != iteration_state::continue_processing) + { + return ret; + } + cmd.setAction(CMD_TIME_CHECK); + return processActionMessage(cmd); } FALLTHROUGH case CMD_TIME_GRANT: @@ -1036,40 +1024,7 @@ iteration_state FederateState::processActionMessage (ActionMessage &cmd) } break; - /* - case CMD_REG_DST_FILTER: - case CMD_NOTIFY_DST_FILTER: - { - if (!checkActionFlag (cmd, clone_flag)) - { - auto endI = getEndpoint (cmd.dest_handle); - if (endI != nullptr) - { - addDependency (cmd.source_id); - } - } - else - { - auto endI = getEndpoint(cmd.dest_handle); - if (endI != nullptr) - { - addDependency(cmd.source_id); - } - } - break; - } - case CMD_REG_SRC_FILTER: - case CMD_NOTIFY_SRC_FILTER: - { - auto endI = getEndpoint (cmd.dest_handle); - if (endI != nullptr) - { - endI->hasFilter = true; - addDependent (cmd.source_id); - } - } - break; - */ + case CMD_FED_ACK: if (state != HELICS_CREATED) { @@ -1087,6 +1042,9 @@ iteration_state FederateState::processActionMessage (ActionMessage &cmd) return iteration_state::next_step; } break; + case CMD_FED_CONFIGURE: + processConfigUpdate(cmd); + break; } return iteration_state::continue_processing; } diff --git a/src/helics/core/ipc/IpcBroker.cpp b/src/helics/core/ipc/IpcBroker.cpp index f943ef3740..bb34b69a61 100644 --- a/src/helics/core/ipc/IpcBroker.cpp +++ b/src/helics/core/ipc/IpcBroker.cpp @@ -44,8 +44,6 @@ IpcBroker::IpcBroker (bool rootBroker) noexcept : CommsBroker (rootBroker) {} IpcBroker::IpcBroker (const std::string &broker_name) : CommsBroker (broker_name) {} -IpcBroker::~IpcBroker () = default; - void IpcBroker::displayHelp (bool local_only) { std::cout << " Help for Interprocess Broker: \n"; diff --git a/src/helics/core/ipc/IpcBroker.h b/src/helics/core/ipc/IpcBroker.h index 07dabf733b..0e773482f1 100644 --- a/src/helics/core/ipc/IpcBroker.h +++ b/src/helics/core/ipc/IpcBroker.h @@ -24,9 +24,6 @@ class IpcBroker final : public CommsBroker static void displayHelp(bool local_only = false); void initializeFromArgs(int argc, const char *const *argv) override; - /**destructor*/ - virtual ~IpcBroker(); - virtual std::string getAddress() const override; private: diff --git a/src/helics/core/ipc/IpcCore.cpp b/src/helics/core/ipc/IpcCore.cpp index de77f68a7e..e007300676 100644 --- a/src/helics/core/ipc/IpcCore.cpp +++ b/src/helics/core/ipc/IpcCore.cpp @@ -42,8 +42,6 @@ IpcCore::IpcCore () noexcept {} IpcCore::IpcCore (const std::string &core_name) : CommsBroker (core_name) {} -IpcCore::~IpcCore () = default; - void IpcCore::initializeFromArgs (int argc, const char *const *argv) { if (brokerState == created) diff --git a/src/helics/core/ipc/IpcCore.h b/src/helics/core/ipc/IpcCore.h index d34f804b9e..9d211d7c8f 100644 --- a/src/helics/core/ipc/IpcCore.h +++ b/src/helics/core/ipc/IpcCore.h @@ -21,8 +21,7 @@ class IpcCore final : public CommsBroker /** default constructor*/ IpcCore () noexcept; IpcCore (const std::string &core_name); - /** destructor*/ - ~IpcCore (); + virtual void initializeFromArgs (int argc, const char *const *argv) override; public: diff --git a/src/helics/core/tcp/TcpBroker.cpp b/src/helics/core/tcp/TcpBroker.cpp index e2bdd192a3..3c072051db 100644 --- a/src/helics/core/tcp/TcpBroker.cpp +++ b/src/helics/core/tcp/TcpBroker.cpp @@ -14,8 +14,6 @@ TcpBroker::TcpBroker (bool rootBroker) noexcept : CommsBroker (rootBroker) {} TcpBroker::TcpBroker (const std::string &broker_name) : CommsBroker (broker_name) {} -TcpBroker::~TcpBroker () = default; - void TcpBroker::displayHelp (bool local_only) { std::cout << " Help for TCP Broker: \n"; diff --git a/src/helics/core/tcp/TcpBroker.h b/src/helics/core/tcp/TcpBroker.h index 4b6f3a69a6..55479c3796 100644 --- a/src/helics/core/tcp/TcpBroker.h +++ b/src/helics/core/tcp/TcpBroker.h @@ -25,9 +25,6 @@ class TcpBroker final : public CommsBroker void initializeFromArgs (int argc, const char *const *argv) override; - /**destructor*/ - virtual ~TcpBroker (); - virtual std::string getAddress () const override; static void displayHelp (bool local_only = false); diff --git a/src/helics/core/tcp/TcpCore.cpp b/src/helics/core/tcp/TcpCore.cpp index 711686925c..5c5bb5444c 100644 --- a/src/helics/core/tcp/TcpCore.cpp +++ b/src/helics/core/tcp/TcpCore.cpp @@ -13,8 +13,6 @@ namespace tcp { TcpCore::TcpCore () noexcept {} -TcpCore::~TcpCore () = default; - TcpCore::TcpCore (const std::string &core_name) : CommsBroker (core_name) {} void TcpCore::initializeFromArgs (int argc, const char *const *argv) diff --git a/src/helics/core/tcp/TcpCore.h b/src/helics/core/tcp/TcpCore.h index 58db4cc347..1c67d6b6bd 100644 --- a/src/helics/core/tcp/TcpCore.h +++ b/src/helics/core/tcp/TcpCore.h @@ -20,7 +20,7 @@ class TcpCore final : public CommsBroker /** default constructor*/ TcpCore () noexcept; TcpCore (const std::string &core_name); - ~TcpCore (); + virtual void initializeFromArgs (int argc, const char *const *argv) override; public: diff --git a/src/helics/core/tcp/TcpHelperClasses.cpp b/src/helics/core/tcp/TcpHelperClasses.cpp index 8e976e5270..5d1dd10d29 100644 --- a/src/helics/core/tcp/TcpHelperClasses.cpp +++ b/src/helics/core/tcp/TcpHelperClasses.cpp @@ -18,22 +18,32 @@ void TcpRxConnection::start () { if (triggerhalt) { + receiving = false; return; } if (state == connection_state_t::prestart) { + receiving = true; state=connection_state_t::halted; } connection_state_t exp = connection_state_t::halted; if (state.compare_exchange_strong (exp, connection_state_t::receiving)) { + if (receiving == false) + { + receiving = true; + } socket_.async_receive (boost::asio::buffer (data.data () + residBufferSize, data.size () - residBufferSize), - [connection = shared_from_this ()](const boost::system::error_code &error, + [this](const boost::system::error_code &error, size_t bytes_transferred) { - connection->handle_read (error, bytes_transferred); + handle_read (error, bytes_transferred); }); } + else if (exp!=connection_state_t::receiving) + { + receiving = false; + } } void TcpRxConnection::setDataCall(std::function dataFunc) @@ -64,6 +74,7 @@ void TcpRxConnection::handle_read (const boost::system::error_code &error, size_ if (triggerhalt) { state = connection_state_t::halted; + receiving = false; return; } if (!error) @@ -88,6 +99,7 @@ void TcpRxConnection::handle_read (const boost::system::error_code &error, size_ else if (error == boost::asio::error::operation_aborted) { state = connection_state_t::halted; + receiving = false; return; } else @@ -116,14 +128,23 @@ void TcpRxConnection::handle_read (const boost::system::error_code &error, size_ state = connection_state_t::halted; start (); } + else + { + receiving = false; + } } else if ((error != boost::asio::error::eof) && (error != boost::asio::error::operation_aborted)) { if (error != boost::asio::error::connection_reset) { std::cerr << "receive error " << error.message () << std::endl; - state = connection_state_t::halted; } + state = connection_state_t::halted; + receiving = false; + } + else + { + receiving = false; } } } @@ -153,6 +174,10 @@ void TcpRxConnection::close () std::cerr << "error occurred sending shutdown::" << ec << std::endl; } socket_.close (); + while (receiving) + { + std::this_thread::yield(); + } } @@ -250,8 +275,13 @@ TcpServer::pointer TcpServer::create (boost::asio::io_service &io_service, int P return pointer (new TcpServer (io_service, PortNum, nominalBufferSize)); } + void TcpServer::start () { + if (halted) + { + return; + } bool exp = false; if (accepting.compare_exchange_strong (exp, true)) { @@ -260,15 +290,18 @@ void TcpServer::start () { for (auto &conn :*connects) { - conn->start (); + if (!conn->isReceiving()) + { + conn->start(); + } } } TcpRxConnection::pointer new_connection = TcpRxConnection::create (acceptor_.get_io_service (), bufferSize); auto &socket = new_connection->socket(); - acceptor_.async_accept (socket, [server = shared_from_this (), connection=std::move(new_connection)]( + acceptor_.async_accept (socket, [this, connection=std::move(new_connection)]( const boost::system::error_code &error) { - server->handle_accept (connection, error); + handle_accept (connection, error); }); } } @@ -287,7 +320,10 @@ void TcpServer::handle_accept (TcpRxConnection::pointer new_connection, const bo connects->push_back(std::move(new_connection)); } accepting = false; - start (); + if (!halted) + { + start(); + } } else if (error != boost::asio::error::operation_aborted) { @@ -302,10 +338,8 @@ void TcpServer::handle_accept (TcpRxConnection::pointer new_connection, const bo void TcpServer::close () { - if (accepting) - { - acceptor_.close(); - } + halted = true; + acceptor_.close(); auto connects = connections.lock(); for (auto &conn : *connects) { diff --git a/src/helics/core/tcp/TcpHelperClasses.h b/src/helics/core/tcp/TcpHelperClasses.h index 31bebd8a80..ad25b5c6d5 100644 --- a/src/helics/core/tcp/TcpHelperClasses.h +++ b/src/helics/core/tcp/TcpHelperClasses.h @@ -29,20 +29,24 @@ class TcpRxConnection : public std::enable_shared_from_this }; typedef std::shared_ptr pointer; - + /** create an RxConnection object using the specified service and bufferSize*/ static pointer create (boost::asio::io_service &io_service, size_t bufferSize) { return pointer (new TcpRxConnection (io_service, bufferSize)); } - + /** get the underlying socket object*/ boost::asio::ip::tcp::socket &socket () { return socket_; } /** start the receiving loop*/ void start(); /** close the socket*/ void close (); - + bool isReceiving() const + { + return receiving.load(); + } + /** set the callback for the data object*/ void setDataCall(std::function dataFunc); - + /** set the callback for an error*/ void setErrorCall(std::function errorFunc); /** send raw data @@ -59,12 +63,13 @@ class TcpRxConnection : public std::enable_shared_from_this : socket_ (io_service), data (bufferSize) { } - + /** function for handling the asynchronous return from a read request*/ void handle_read (const boost::system::error_code &error, size_t bytes_transferred); std::atomic residBufferSize{0}; boost::asio::ip::tcp::socket socket_; std::vector data; std::atomic triggerhalt{ false }; + std::atomic receiving{ false }; std::function dataCall; std::function errorCall; std::atomic state{connection_state_t::prestart}; @@ -214,6 +219,7 @@ class TcpServer : public std::enable_shared_from_this size_t bufferSize; std::function dataCall; std::function errorCall; + std::atomic halted{ false }; guarded>> connections; }; diff --git a/src/helics/core/udp/UdpBroker.cpp b/src/helics/core/udp/UdpBroker.cpp index 2d27b377ab..fcbfc4ba59 100644 --- a/src/helics/core/udp/UdpBroker.cpp +++ b/src/helics/core/udp/UdpBroker.cpp @@ -15,8 +15,6 @@ UdpBroker::UdpBroker (bool rootBroker) noexcept : CommsBroker (rootBroker) {} UdpBroker::UdpBroker (const std::string &broker_name) : CommsBroker (broker_name) {} -UdpBroker::~UdpBroker () = default; - void UdpBroker::displayHelp (bool local_only) { std::cout << " Help for UDP Broker: \n"; diff --git a/src/helics/core/udp/UdpBroker.h b/src/helics/core/udp/UdpBroker.h index f2f2c8f1a0..54226aad03 100644 --- a/src/helics/core/udp/UdpBroker.h +++ b/src/helics/core/udp/UdpBroker.h @@ -25,9 +25,6 @@ class UdpBroker final : public CommsBroker void initializeFromArgs (int argc, const char *const *argv) override; - /**destructor*/ - virtual ~UdpBroker (); - virtual std::string getAddress () const override; static void displayHelp (bool local_only = false); diff --git a/src/helics/core/udp/UdpCore.cpp b/src/helics/core/udp/UdpCore.cpp index 3f6c1c8d7b..33889aa9de 100644 --- a/src/helics/core/udp/UdpCore.cpp +++ b/src/helics/core/udp/UdpCore.cpp @@ -1,9 +1,9 @@ /* - Copyright © 2017-2018, Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable Energy, LLC All rights reserved. See LICENSE file and DISCLAIMER for more details. */ + #include "UdpCore.h" #include "UdpComms.h" @@ -13,8 +13,6 @@ namespace udp { UdpCore::UdpCore () noexcept {} -UdpCore::~UdpCore () = default; - UdpCore::UdpCore (const std::string &core_name) : CommsBroker (core_name) {} void UdpCore::initializeFromArgs (int argc, const char *const *argv) diff --git a/src/helics/core/udp/UdpCore.h b/src/helics/core/udp/UdpCore.h index 67fef70c7f..7e56741787 100644 --- a/src/helics/core/udp/UdpCore.h +++ b/src/helics/core/udp/UdpCore.h @@ -19,7 +19,6 @@ class UdpCore final : public CommsBroker /** default constructor*/ UdpCore() noexcept; UdpCore(const std::string &core_name); - ~UdpCore(); virtual void initializeFromArgs(int argc, const char *const *argv) override; public: diff --git a/src/helics/core/zmq/ZmqBroker.cpp b/src/helics/core/zmq/ZmqBroker.cpp index 228c8f8ae0..7d5ed79eb4 100644 --- a/src/helics/core/zmq/ZmqBroker.cpp +++ b/src/helics/core/zmq/ZmqBroker.cpp @@ -15,8 +15,6 @@ ZmqBroker::ZmqBroker (bool rootBroker) noexcept : CommsBroker (rootBroker) {} ZmqBroker::ZmqBroker (const std::string &broker_name) : CommsBroker (broker_name) {} -ZmqBroker::~ZmqBroker () = default; - void ZmqBroker::displayHelp (bool local_only) { std::cout << " Help for Zero MQ Broker: \n"; diff --git a/src/helics/core/zmq/ZmqBroker.h b/src/helics/core/zmq/ZmqBroker.h index 7065dcd3a7..415c15fcf5 100644 --- a/src/helics/core/zmq/ZmqBroker.h +++ b/src/helics/core/zmq/ZmqBroker.h @@ -26,9 +26,6 @@ class ZmqBroker final:public CommsBroker void initializeFromArgs(int argc, const char * const *argv) override; - /**destructor*/ - virtual ~ZmqBroker(); - virtual std::string getAddress() const override; static void displayHelp(bool local_only = false); private: diff --git a/src/helics/core/zmq/ZmqCore.cpp b/src/helics/core/zmq/ZmqCore.cpp index be5574ba4f..dd53ab0fe7 100644 --- a/src/helics/core/zmq/ZmqCore.cpp +++ b/src/helics/core/zmq/ZmqCore.cpp @@ -13,8 +13,6 @@ namespace zeromq { ZmqCore::ZmqCore () noexcept {} -ZmqCore::~ZmqCore () = default; - ZmqCore::ZmqCore (const std::string &core_name) : CommsBroker (core_name) {} void ZmqCore::initializeFromArgs (int argc, const char *const *argv) diff --git a/src/helics/core/zmq/ZmqCore.h b/src/helics/core/zmq/ZmqCore.h index 0d47e224fb..0250a339f0 100644 --- a/src/helics/core/zmq/ZmqCore.h +++ b/src/helics/core/zmq/ZmqCore.h @@ -22,8 +22,7 @@ class ZmqCore final: public CommsBroker { ZmqCore() noexcept; /** construct from with a core name*/ ZmqCore(const std::string &core_name); - /** destructor*/ - ~ZmqCore(); + virtual void initializeFromArgs (int argc, const char * const *argv) override; public: diff --git a/src/helics/shared_api_library/FederateExport.cpp b/src/helics/shared_api_library/FederateExport.cpp index f173fd9448..1082a2ad71 100644 --- a/src/helics/shared_api_library/FederateExport.cpp +++ b/src/helics/shared_api_library/FederateExport.cpp @@ -93,15 +93,23 @@ std::shared_ptr getMessageFedSharedPtr (helics_federate helics_federate helicsCreateValueFederate (const helics_federate_info_t fi) { auto *fed = new helics::FedObject; - fed->index = getMasterHolder ()->addFed (fed); - if (fi == nullptr) + try { - fed->fedptr = std::make_shared (helics::FederateInfo ()); + if (fi == nullptr) + { + fed->fedptr = std::make_shared(helics::FederateInfo()); + } + else + { + fed->fedptr = std::make_shared(*reinterpret_cast (fi)); + } } - else + catch (const helics::RegistrationFailure &) { - fed->fedptr = std::make_shared (*reinterpret_cast (fi)); + delete fed; + return nullptr; } + fed->index = getMasterHolder()->addFed(fed); fed->type = helics::vtype::valueFed; fed->valid = fedValidationIdentifier; return reinterpret_cast (fed); @@ -110,8 +118,16 @@ helics_federate helicsCreateValueFederate (const helics_federate_info_t fi) helics_federate helicsCreateValueFederateFromJson (const char *json) { auto *fed = new helics::FedObject; - fed->index = getMasterHolder ()->addFed (fed); - fed->fedptr = std::make_shared ((json != nullptr) ? std::string (json) : std::string ()); + try + { + fed->fedptr = std::make_shared((json != nullptr) ? std::string(json) : std::string()); + } + catch (const helics::RegistrationFailure &) + { + delete fed; + return nullptr; + } + fed->index = getMasterHolder()->addFed(fed); fed->type = helics::vtype::valueFed; fed->valid = fedValidationIdentifier; return reinterpret_cast (fed); @@ -121,15 +137,24 @@ helics_federate helicsCreateValueFederateFromJson (const char *json) helics_federate helicsCreateMessageFederate (const helics_federate_info_t fi) { auto *fed = new helics::FedObject; - fed->index = getMasterHolder ()->addFed (fed); - if (fi == nullptr) + try { - fed->fedptr = std::make_shared (helics::FederateInfo ()); + if (fi == nullptr) + { + fed->fedptr = std::make_shared(helics::FederateInfo()); + } + else + { + fed->fedptr = std::make_shared(*reinterpret_cast (fi)); + } } - else + catch (const helics::RegistrationFailure &) { - fed->fedptr = std::make_shared (*reinterpret_cast (fi)); + delete fed; + return nullptr; } + + fed->index = getMasterHolder()->addFed(fed); fed->type = helics::vtype::messageFed; fed->valid = fedValidationIdentifier; return reinterpret_cast (fed); @@ -138,8 +163,17 @@ helics_federate helicsCreateMessageFederate (const helics_federate_info_t fi) helics_federate helicsCreateMessageFederateFromJson (const char *json) { auto *fed = new helics::FedObject; - fed->index = getMasterHolder ()->addFed (fed); - fed->fedptr = std::make_shared ((json != nullptr) ? std::string (json) : std::string ()); + + try + { + fed->fedptr = std::make_shared((json != nullptr) ? std::string(json) : std::string()); + } + catch (const helics::RegistrationFailure &) + { + delete fed; + return nullptr; + } + fed->index = getMasterHolder()->addFed(fed); fed->type = helics::vtype::messageFed; fed->valid = fedValidationIdentifier; return reinterpret_cast (fed); @@ -149,15 +183,23 @@ helics_federate helicsCreateMessageFederateFromJson (const char *json) helics_federate helicsCreateCombinationFederate (const helics_federate_info_t fi) { auto *fed = new helics::FedObject; - fed->index = getMasterHolder ()->addFed (fed); - if (fi == nullptr) + try { - fed->fedptr = std::make_shared (helics::FederateInfo ()); + if (fi == nullptr) + { + fed->fedptr = std::make_shared(helics::FederateInfo()); + } + else + { + fed->fedptr = std::make_shared(*reinterpret_cast (fi)); + } } - else + catch (const helics::RegistrationFailure &) { - fed->fedptr = std::make_shared (*reinterpret_cast (fi)); + delete fed; + return nullptr; } + fed->index = getMasterHolder()->addFed(fed); fed->type = helics::vtype::combinationFed; fed->valid = fedValidationIdentifier; return reinterpret_cast (fed); @@ -166,8 +208,17 @@ helics_federate helicsCreateCombinationFederate (const helics_federate_info_t fi helics_federate helicsCreateCombinationFederateFromJson (const char *json) { auto *fed = new helics::FedObject; - fed->index = getMasterHolder ()->addFed (fed); - fed->fedptr = std::make_shared ((json != nullptr) ? std::string (json) : std::string ()); + try + { + fed->fedptr = std::make_shared((json != nullptr) ? std::string(json) : std::string()); + } + catch (const helics::RegistrationFailure &) + { + delete fed; + return nullptr; + } + + fed->index = getMasterHolder()->addFed(fed); fed->type = helics::vtype::combinationFed; fed->valid = fedValidationIdentifier; return reinterpret_cast (fed); diff --git a/tests/helics/application_api/CMakeLists.txt b/tests/helics/application_api/CMakeLists.txt index 680e5825fa..81e6f2073f 100644 --- a/tests/helics/application_api/CMakeLists.txt +++ b/tests/helics/application_api/CMakeLists.txt @@ -91,9 +91,9 @@ target_compile_definitions(application-api-tests PRIVATE "-DQUICK_TESTS_ONLY") target_compile_definitions(key-tests PRIVATE "-DKEY_TESTS") add_test(NAME key-tests COMMAND key-tests --log_level=message --report_level=short) -add_test(NAME application-api-tests COMMAND application-api-tests --log_level=test_suite --report_level=short) +add_test(NAME application-api-tests COMMAND application-api-tests --log_level=message --report_level=short) -add_test(NAME extended-api-tests COMMAND extended-api-tests --log_level=test_suite --report_level=short) +add_test(NAME extended-api-tests COMMAND extended-api-tests --log_level=message --report_level=short) foreach(keyfile IN LISTS KEY_LIBRARY_FILES) diff --git a/tests/helics/application_api/TimingTests.cpp b/tests/helics/application_api/TimingTests.cpp index 1860f5f0ba..1ad73c0a6d 100644 --- a/tests/helics/application_api/TimingTests.cpp +++ b/tests/helics/application_api/TimingTests.cpp @@ -147,4 +147,48 @@ BOOST_AUTO_TEST_CASE (timing_with_impact_window) vFed2 ->finalize (); // this will also test finalizing while a time request is ongoing otherwise it will time out. } + +BOOST_AUTO_TEST_CASE(timing_with_minDelta_change) +{ + SetupTest("test", 1,1.0); + auto vFed1 = GetFederateAs(0); + + vFed1->enterExecutionState(); + + auto res = vFed1->requestTime(1.0); + // check that the request is only granted at the appropriate period + + BOOST_CHECK_EQUAL(res, 1.0); + + //purposely requesting 1.0 to test min delta + res = vFed1->requestTime(1.0); + BOOST_CHECK_EQUAL(res, 2.0); + + vFed1->setTimeDelta(0.1); + res = vFed1->requestTime(res); + BOOST_CHECK_EQUAL(res, 2.1); + vFed1->finalize(); +} + +BOOST_AUTO_TEST_CASE(timing_with_period_change) +{ + SetupTest("test", 1); + auto vFed1 = GetFederateAs(0); + vFed1->setPeriod(1.0); + vFed1->enterExecutionState(); + + auto res = vFed1->requestTime(1.0); + // check that the request is only granted at the appropriate period + + BOOST_CHECK_EQUAL(res, 1.0); + + //purposely requesting 1.0 to test min delta + res = vFed1->requestTime(1.0); + BOOST_CHECK_EQUAL(res, 2.0); + + vFed1->setPeriod(0.1); + res = vFed1->requestTime(res); + BOOST_CHECK_EQUAL(res, 2.1); + vFed1->finalize(); +} BOOST_AUTO_TEST_SUITE_END () diff --git a/tests/helics/apps/PlayerTests.cpp b/tests/helics/apps/PlayerTests.cpp index 35ac0e7487..e581b4e614 100644 --- a/tests/helics/apps/PlayerTests.cpp +++ b/tests/helics/apps/PlayerTests.cpp @@ -541,6 +541,18 @@ BOOST_DATA_TEST_CASE (simple_message_player_test_files, boost::unit_test::data:: fut.get (); } +BOOST_AUTO_TEST_CASE(player_test_help) +{ + StringToCmdLine cmdArg("--version --quiet"); + helics::apps::Player play1(cmdArg.getArgCount(),cmdArg.getArgV()); + + BOOST_CHECK(!play1.isActive()); + + StringToCmdLine cmdArg2("-? --quiet"); + helics::apps::Player play2(cmdArg2.getArgCount(), cmdArg2.getArgV()); + + BOOST_CHECK(!play2.isActive()); +} /* BOOST_AUTO_TEST_CASE (simple_player_test) { diff --git a/tests/helics/apps/RecorderTests.cpp b/tests/helics/apps/RecorderTests.cpp index 1a465ebfd8..f91f072e05 100644 --- a/tests/helics/apps/RecorderTests.cpp +++ b/tests/helics/apps/RecorderTests.cpp @@ -694,4 +694,18 @@ BOOST_AUTO_TEST_CASE (recorder_test_saveFile3) boost::filesystem::remove (filename); boost::filesystem::remove (filename2); } + +BOOST_AUTO_TEST_CASE(recorder_test_help) +{ + StringToCmdLine cmdArg("--version --quiet"); + helics::apps::Recorder rec1(cmdArg.getArgCount(), cmdArg.getArgV()); + + BOOST_CHECK(!rec1.isActive()); + + StringToCmdLine cmdArg2("-? --quiet"); + helics::apps::Recorder rec2(cmdArg2.getArgCount(), cmdArg2.getArgV()); + + BOOST_CHECK(!rec2.isActive()); +} + BOOST_AUTO_TEST_SUITE_END () diff --git a/tests/helics/apps/SourceTests.cpp b/tests/helics/apps/SourceTests.cpp index 8538431f34..f2ae30dbb5 100644 --- a/tests/helics/apps/SourceTests.cpp +++ b/tests/helics/apps/SourceTests.cpp @@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE (simple_source_test2) src1.finalize (); }); vfed.enterExecutionState (); - auto retTime = vfed.requestTime (5); + auto retTime = vfed.requestTime (1.1); BOOST_CHECK_EQUAL (retTime, 1.0); auto val = sub1.getValue (); BOOST_CHECK_EQUAL (val, 1.3); @@ -189,9 +189,9 @@ BOOST_AUTO_TEST_CASE (sine_source_test) BOOST_AUTO_TEST_CASE (simple_source_test_file) { - helics::FederateInfo fi ("player1"); + helics::FederateInfo fi ("source1"); fi.coreType = helics::core_type::TEST; - fi.coreName = "core1"; + fi.coreName = "corep"; fi.coreInitString = "2"; helics::apps::Source src1 (fi); src1.loadFile (std::string (TEST_DIR) + "/test_files/simple_source_test.json"); @@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE (simple_source_test_file) src1.finalize (); }); vfed.enterExecutionState (); - auto retTime = vfed.requestTime (5); + auto retTime = vfed.requestTime (1.1); BOOST_CHECK_EQUAL (retTime, 1.0); auto val = sub1.getValue (); BOOST_CHECK_EQUAL (val, 1.3); diff --git a/tests/helics/core/ZeromqCore-tests.cpp b/tests/helics/core/ZeromqCore-tests.cpp index e217fb511d..df17de5c0e 100644 --- a/tests/helics/core/ZeromqCore-tests.cpp +++ b/tests/helics/core/ZeromqCore-tests.cpp @@ -162,12 +162,17 @@ BOOST_AUTO_TEST_CASE (zmqRequestSet_test2) repSocket3.send (msg); // make sure the check receives all messages - reqset.checkForMessages (std::chrono::milliseconds (150)); + reqset.checkForMessages (std::chrono::milliseconds (50)); if (reqset.waiting ()) { - reqset.checkForMessages (std::chrono::milliseconds (150)); + reqset.checkForMessages (std::chrono::milliseconds (50)); } - BOOST_CHECK (!reqset.waiting ()); + //since we have 3 sockets we might have to do this twice since it returns immediately if it has a message + if (reqset.waiting()) + { + reqset.checkForMessages(std::chrono::milliseconds(50)); + } + BOOST_REQUIRE (!reqset.waiting ()); reqset.transmit (1, M); reqset.transmit (2, M); reqset.transmit (3, M); @@ -378,7 +383,7 @@ BOOST_AUTO_TEST_CASE (zmqComm_transmit_add_route) std::atomic counter2{0}; std::atomic counter3{0}; helics::zeromq::ZmqComms comm (host, host); - helics::zeromq::ZmqComms comm2 (host, ""); + helics::zeromq::ZmqComms comm2 (host, std::string()); helics::zeromq::ZmqComms comm3 (host, host); comm.setBrokerPort (23405); @@ -420,13 +425,25 @@ BOOST_AUTO_TEST_CASE (zmqComm_transmit_add_route) comm.transmit (0, helics::CMD_ACK); - std::this_thread::sleep_for (std::chrono::milliseconds (250)); + std::this_thread::yield(); + if (counter2 != 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } BOOST_REQUIRE_EQUAL (counter2, 1); BOOST_CHECK (act2.lock()->action () == helics::action_message_def::action_t::cmd_ack); comm3.transmit (0, helics::CMD_ACK); - std::this_thread::sleep_for (std::chrono::milliseconds (250)); + std::this_thread::yield(); + if (counter2 != 2) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + if (counter2 != 2) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } BOOST_REQUIRE_EQUAL (counter2, 2); BOOST_CHECK (act2.lock()->action () == helics::action_message_def::action_t::cmd_ack); @@ -434,10 +451,14 @@ BOOST_AUTO_TEST_CASE (zmqComm_transmit_add_route) comm2.transmit (3, helics::CMD_ACK); - std::this_thread::sleep_for (std::chrono::milliseconds (250)); + std::this_thread::yield(); + if (counter3 != 1) + { + std::this_thread::sleep_for (std::chrono::milliseconds (200)); + } if (counter3 != 1) { - std::this_thread::sleep_for (std::chrono::milliseconds (250)); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } BOOST_REQUIRE_EQUAL (counter3, 1); BOOST_CHECK (act3.lock()->action () == helics::action_message_def::action_t::cmd_ack); @@ -446,7 +467,15 @@ BOOST_AUTO_TEST_CASE (zmqComm_transmit_add_route) comm2.transmit (4, helics::CMD_ACK); - std::this_thread::sleep_for (std::chrono::milliseconds (250)); + std::this_thread::yield(); + if (counter != 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + if (counter != 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } BOOST_REQUIRE_EQUAL (counter, 1); BOOST_CHECK (act.lock()->action () == helics::action_message_def::action_t::cmd_ack); diff --git a/tests/python_helics/test_message_filter.py b/tests/python_helics/test_message_filter.py index 235b29f616..10b01adaf3 100644 --- a/tests/python_helics/test_message_filter.py +++ b/tests/python_helics/test_message_filter.py @@ -94,6 +94,7 @@ def test_message_filter_registration(broker): FreeFederate(fFed) FreeFederate(mFed) + time.sleep(1.0) def test_message_filter_function(broker): @@ -116,10 +117,7 @@ def test_message_filter_function(broker): assert status == 0 assert state == 2 data = "hello world" - # TODO: Fix segfaults on the next line h.helicsEndpointSendMessageRaw(p1, "port2", data) - - # TODO: Also segfaults grantedtime = h.helicsFederateRequestTimeAsync (mFed, 1.0) assert grantedtime == 0 status, grantedtime = h.helicsFederateRequestTime(fFed, 1.0) @@ -129,12 +127,11 @@ def test_message_filter_function(broker): assert status == 0 assert grantedtime == 1.0 - f2 = h.helicsFederateRegisterDestinationFilter (fFed, h.helics_custom_filter, "filter2", "port2") - ep1 = h.helicsFederateRegisterEndpoint (fFed, "fout", "") - f3 = h.helicsFederateRegisterSourceFilter (fFed, h.helics_custom_filter, "", "filter0/fout") + h.helicsFederateFinalize(mFed) + h.helicsFederateFinalize(fFed) + #f2 = h.helicsFederateRegisterDestinationFilter (fFed, h.helics_custom_filter, "filter2", "port2") + #ep1 = h.helicsFederateRegisterEndpoint (fFed, "fout", "") + #f3 = h.helicsFederateRegisterSourceFilter (fFed, h.helics_custom_filter, "", "filter0/fout") FreeFederate(fFed) FreeFederate(mFed) - - -