mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-15 09:31:45 +00:00
Compare commits
30 Commits
v1.2.0
...
v1.2.7-pat
Author | SHA1 | Date | |
---|---|---|---|
|
e642262468 | ||
|
9bab3f9f4c | ||
|
ee3a84ce7a | ||
|
f05118f4eb | ||
|
21419adb40 | ||
|
1554c1c273 | ||
|
59b04a1a64 | ||
|
653e82cab4 | ||
|
96e2076300 | ||
|
2894af803b | ||
|
8b88e67360 | ||
|
ca694e4054 | ||
|
3f96181ffd | ||
|
72f5cdef58 | ||
|
811e716731 | ||
|
5ab21946f8 | ||
|
30367eb76d | ||
|
89d71ce14c | ||
|
e54db27242 | ||
|
cc4a8b8f7f | ||
|
e4c349888d | ||
|
436f79bee5 | ||
|
2a6e4de72c | ||
|
e295978b3e | ||
|
e4d73f1a9a | ||
|
d93dc2f7f7 | ||
|
7a4fd96b27 | ||
|
155618af57 | ||
|
9906475b6f | ||
|
de7ddc0ddd |
@@ -42,13 +42,17 @@ if(BUILD_FAIRMQ)
|
||||
find_package2(PUBLIC Boost VERSION 1.64 REQUIRED
|
||||
COMPONENTS program_options thread system filesystem regex date_time signals
|
||||
)
|
||||
find_package2(PUBLIC FairLogger VERSION 1.0.6 REQUIRED)
|
||||
find_package2(PUBLIC FairLogger VERSION 1.2.0 REQUIRED)
|
||||
find_package2(PRIVATE ZeroMQ VERSION 4.1.5 REQUIRED)
|
||||
endif()
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
find_package2(PRIVATE nanomsg VERSION 1.0.0 REQUIRED)
|
||||
find_package2(PRIVATE msgpack VERSION 2.1.5 REQUIRED)
|
||||
find_package2(PRIVATE msgpack VERSION 3.0.0)
|
||||
set(PROJECT_msgpack_VERSION 2.1.5)
|
||||
if(NOT msgpack_FOUND)
|
||||
find_package2(PRIVATE msgpack VERSION 2.1.5 REQUIRED)
|
||||
endif()
|
||||
set(msgpack_ROOT ${PACKAGE_PREFIX_DIR})
|
||||
endif()
|
||||
|
||||
@@ -94,6 +98,7 @@ if(BUILD_DOCS)
|
||||
set(DOXYGEN_PROJECT_NUMBER ${PROJECT_GIT_VERSION})
|
||||
set(DOXYGEN_PROJECT_BRIEF "C++ Message Passing Framework")
|
||||
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
|
||||
set(DOXYGEN_HTML_FOOTER docs/footer.html)
|
||||
doxygen_add_docs(doxygen README.md fairmq)
|
||||
add_custom_target(docs ALL DEPENDS doxygen)
|
||||
endif()
|
||||
|
@@ -2,6 +2,7 @@ Aphecetche, Laurent
|
||||
Binet, Sebastien
|
||||
Eulisse, Giulio
|
||||
Karabowicz, Radoslaw
|
||||
Kretz, Matthias <kretz@kde.org>
|
||||
Krzewicki, Mikolaj
|
||||
Neskovic, Gvozden
|
||||
Richter, Matthias
|
||||
|
6
Jenkinsfile
vendored
6
Jenkinsfile
vendored
@@ -37,9 +37,9 @@ pipeline{
|
||||
steps{
|
||||
script {
|
||||
parallel(buildMatrix([
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc4.9', fairsoft: 'apr18'],
|
||||
[os: 'MacOS10.11', arch: 'x86_64', compiler: 'AppleLLVM8.0.0', fairsoft: 'apr18'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM9.0.0', fairsoft: 'apr18'],
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc4.9', fairsoft: 'may18'],
|
||||
[os: 'MacOS10.11', arch: 'x86_64', compiler: 'AppleLLVM8.0.0', fairsoft: 'may18'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM9.0.0', fairsoft: 'may18'],
|
||||
]) { spec, label ->
|
||||
sh '''\
|
||||
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
|
||||
|
@@ -35,9 +35,9 @@ pipeline{
|
||||
steps{
|
||||
script {
|
||||
parallel(buildMatrix([
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc4.9', fairsoft: 'apr18'],
|
||||
[os: 'MacOS10.11', arch: 'x86_64', compiler: 'AppleLLVM8.0.0', fairsoft: 'apr18'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM9.0.0', fairsoft: 'apr18'],
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc4.9', fairsoft: 'may18'],
|
||||
[os: 'MacOS10.11', arch: 'x86_64', compiler: 'AppleLLVM8.0.0', fairsoft: 'may18'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM9.0.0', fairsoft: 'may18'],
|
||||
]) { spec, label ->
|
||||
sh '''\
|
||||
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
|
||||
|
9
PULL_REQUEST_TEMPLATE.md
Normal file
9
PULL_REQUEST_TEMPLATE.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Replace me with your description.
|
||||
|
||||
---
|
||||
|
||||
Checklist:
|
||||
|
||||
* [ ] Rebased against `dev` branch
|
||||
* [ ] My name is in the resp. CONTRIBUTORS/AUTHORS file
|
||||
* [ ] Followed [the seven rules of great commit messages](https://chris.beams.io/posts/git-commit/#seven-rules)
|
18
README.md
18
README.md
@@ -23,7 +23,7 @@ In addition to this core functionality FairMQ provides a framework for creating
|
||||
are communicating through message passing. FairMQ does not only allow the user to use different transport but also to mix them; i.e: A Device can communicate using different transport on different channels at the same time. Device execution is modelled as a simple state machine that
|
||||
shapes the integration points for the user task. Devices also incorporate a plugin system for runtime configuration and control.
|
||||
Next to the provided devices and plugins (e.g. [DDS](https://github.com/FairRootGroup/DDS))
|
||||
the user can extened FairMQ by developing his own plugins to integrate his devices with external
|
||||
the user can extend FairMQ by developing his own plugins to integrate his devices with external
|
||||
configuration and control services.
|
||||
|
||||
FairMQ has been developed in the context of its mother project [FairRoot](https://github.com/FairRootGroup/FairRoot) -
|
||||
@@ -49,6 +49,8 @@ a simulation, reconstruction and analysis framework.
|
||||
|
||||
| Stable release | Date | API Docs |
|
||||
| --- | --- | --- |
|
||||
| [**1.2.3**](https://github.com/FairRootGroup/FairMQ/releases/tag/v1.2.3) | May 2018 | [link](https://fairrootgroup.github.io/FairMQ/v1.2.3/index.html) |
|
||||
| [**1.2.1**](https://github.com/FairRootGroup/FairMQ/releases/tag/v1.2.1) | May 2018 | [link](https://fairrootgroup.github.io/FairMQ/v1.2.1/index.html) |
|
||||
| [**1.2.0**](https://github.com/FairRootGroup/FairMQ/releases/tag/v1.2.0) | May 2018 | [link](https://fairrootgroup.github.io/FairMQ/v1.2.0/index.html) |
|
||||
|
||||
Find all FairMQ stable and development releases [here](https://github.com/FairRootGroup/FairMQ/releases).
|
||||
@@ -79,14 +81,16 @@ set(CMAKE_PREFIX_PATH /path/to/FairMQ_install_prefix ${CMAKE_PREFIX_PATH})
|
||||
find_package(FairMQ)
|
||||
```
|
||||
|
||||
`find_package(FairMQ)` will define an imported target `FairMQ::FairMQ` (An alias `FairRoot::FairMQ` is also defined (if you use CMake 3.11+) for backwards compatibility, but it is deprecated).
|
||||
`find_package(FairMQ)` will define an imported target `FairMQ::FairMQ`.
|
||||
|
||||
In order to succesfully compile and link against the `FairMQ::FairMQ` target, you need to discover its public package dependencies, too.
|
||||
|
||||
```cmake
|
||||
find_package(FairMQ)
|
||||
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
|
||||
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_BOOST_COMPONENTS})
|
||||
if(FairMQ_FOUND)
|
||||
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
|
||||
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_BOOST_COMPONENTS})
|
||||
endif()
|
||||
```
|
||||
|
||||
Of course, feel free to customize the above commands to your needs.
|
||||
@@ -95,8 +99,10 @@ Optionally, you can require certain FairMQ package components and a minimum vers
|
||||
|
||||
```cmake
|
||||
find_package(FairMQ 1.1.0 COMPONENTS nanomsg_transport dds_plugin)
|
||||
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
|
||||
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_BOOST_COMPONENTS})
|
||||
if(FairMQ_FOUND)
|
||||
find_package(FairLogger ${FairMQ_FairLogger_VERSION})
|
||||
find_package(Boost ${FairMQ_Boost_VERSION} COMPONENTS ${FairMQ_BOOST_COMPONENTS})
|
||||
endif()
|
||||
```
|
||||
|
||||
When building FairMQ, CMake will print a summary table of all available package components.
|
||||
|
@@ -32,9 +32,4 @@ set(CMAKE_MODULE_PATH ${@PROJECT_NAME@_CMAKEMODDIR} ${CMAKE_MODULE_PATH})
|
||||
### Import targets
|
||||
include(@PACKAGE_CMAKE_INSTALL_PREFIX@/@PACKAGE_INSTALL_DESTINATION@/@PROJECT_EXPORT_SET@.cmake)
|
||||
|
||||
### Alias target for backwards compat (DEPRECATED)
|
||||
if((NOT TARGET FairRoot::@PROJECT_NAME@) AND (CMAKE_VERSION VERSION_GREATER 3.10.99))
|
||||
add_library(FairRoot::@PROJECT_NAME@ ALIAS @PROJECT_NAME@::@PROJECT_NAME@)
|
||||
endif()
|
||||
|
||||
@PACKAGE_COMPONENTS@
|
||||
|
@@ -280,20 +280,22 @@ macro(find_package2 qualifier pkgname)
|
||||
set(CMAKE_PREFIX_PATH ${old_CPP})
|
||||
unset(old_CPP)
|
||||
|
||||
if(${qualifier} STREQUAL PRIVATE)
|
||||
set(PROJECT_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL PUBLIC)
|
||||
set(PROJECT_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL INTERFACE)
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
if(${pkgname}_FOUND)
|
||||
if(${qualifier} STREQUAL PRIVATE)
|
||||
set(PROJECT_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL PUBLIC)
|
||||
set(PROJECT_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL INTERFACE)
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${ARGS_VERSION})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
1
docs/footer.html
Normal file
1
docs/footer.html
Normal file
@@ -0,0 +1 @@
|
||||
<p style="margin: 0 12px 10px 12px;"><a href="https://help.github.com/articles/github-privacy-statement/">privacy</a></p>
|
@@ -31,8 +31,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-1-1.sh.in ${CMAKE_CUR
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh)
|
||||
|
||||
add_test(NAME Example-1-1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh)
|
||||
set_tests_properties(Example-1-1 PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
add_test(NAME Example-1-1-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh zeromq)
|
||||
set_tests_properties(Example-1-1-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-1-1-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh nanomsg)
|
||||
set_tests_properties(Example-1-1-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example-1-1-shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-1.sh shmem)
|
||||
set_tests_properties(Example-1-1-shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -1,10 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
# setup a trap to kill everything if the test fails/timeouts
|
||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID;' TERM
|
||||
|
||||
SAMPLER="fairmq-ex-1-1-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --verbosity veryhigh"
|
||||
SAMPLER+=" --control static --color false"
|
||||
SAMPLER+=" --max-iterations 1"
|
||||
@@ -14,6 +23,7 @@ SAMPLER_PID=$!
|
||||
|
||||
SINK="fairmq-ex-1-1-sink"
|
||||
SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --verbosity veryhigh"
|
||||
SINK+=" --control static --color false"
|
||||
SINK+=" --max-iterations 1"
|
||||
|
@@ -39,8 +39,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ex-1-n-1.json ${CMAKE_CURRENT_BINARY_
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-1-n-1.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh)
|
||||
|
||||
add_test(NAME Example-1-n-1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh)
|
||||
set_tests_properties(Example-1-n-1 PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
add_test(NAME Example-1-n-1-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh zeromq)
|
||||
set_tests_properties(Example-1-n-1-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-1-n-1-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh nanomsg)
|
||||
set_tests_properties(Example-1-n-1-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example-1-n-1-shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-1-n-1.sh shmem)
|
||||
set_tests_properties(Example-1-n-1-shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received: ")
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -2,6 +2,12 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
ex2config="@CMAKE_CURRENT_BINARY_DIR@/ex-1-n-1.json"
|
||||
|
||||
# setup a trap to kill everything if the test fails/timeouts
|
||||
@@ -9,6 +15,7 @@ trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $PROCESSOR1_PID;
|
||||
|
||||
SAMPLER="fairmq-ex-1-n-1-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --verbosity veryhigh"
|
||||
SAMPLER+=" --control static --color false"
|
||||
SAMPLER+=" --max-iterations 2"
|
||||
@@ -18,6 +25,7 @@ SAMPLER_PID=$!
|
||||
|
||||
PROCESSOR1="fairmq-ex-1-n-1-processor"
|
||||
PROCESSOR1+=" --id processor1"
|
||||
PROCESSOR1+=" --transport $transport"
|
||||
PROCESSOR1+=" --verbosity veryhigh"
|
||||
PROCESSOR1+=" --control static --color false"
|
||||
PROCESSOR1+=" --mq-config $ex2config"
|
||||
@@ -27,6 +35,7 @@ PROCESSOR1_PID=$!
|
||||
|
||||
PROCESSOR2="fairmq-ex-1-n-1-processor"
|
||||
PROCESSOR2+=" --id processor2"
|
||||
PROCESSOR2+=" --transport $transport"
|
||||
PROCESSOR2+=" --verbosity veryhigh"
|
||||
PROCESSOR2+=" --control static --color false"
|
||||
PROCESSOR2+=" --mq-config $ex2config"
|
||||
@@ -36,6 +45,7 @@ PROCESSOR2_PID=$!
|
||||
|
||||
SINK="fairmq-ex-1-n-1-sink"
|
||||
SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --verbosity veryhigh"
|
||||
SINK+=" --control static --color false"
|
||||
SINK+=" --max-iterations 2"
|
||||
|
@@ -12,6 +12,8 @@ add_subdirectory(copypush)
|
||||
add_subdirectory(dds)
|
||||
add_subdirectory(multipart)
|
||||
add_subdirectory(multiple-channels)
|
||||
add_subdirectory(multiple-transports)
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_subdirectory(multiple-transports)
|
||||
endif()
|
||||
add_subdirectory(region)
|
||||
add_subdirectory(req-rep)
|
||||
|
@@ -32,8 +32,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-copypush.sh.in ${CMAK
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-copypush.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh)
|
||||
|
||||
add_test(NAME Example-CopyPush COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh)
|
||||
set_tests_properties(Example-CopyPush PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
add_test(NAME Example-CopyPush-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh zeromq)
|
||||
set_tests_properties(Example-CopyPush-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-CopyPush-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh nanomsg)
|
||||
set_tests_properties(Example-CopyPush-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example-CopyPush-shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-copypush.sh shmem)
|
||||
set_tests_properties(Example-CopyPush-shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message: ")
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -2,11 +2,18 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
# setup a trap to kill everything if the test fails/timeouts
|
||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK1_PID; kill -TERM $SINK2_PID; wait $SAMPLER_PID; wait $SINK1_PID; wait $SINK2_PID;' TERM
|
||||
|
||||
SAMPLER="fairmq-ex-copypush-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --verbosity veryhigh"
|
||||
SAMPLER+=" --control static --color false"
|
||||
SAMPLER+=" --max-iterations 1"
|
||||
@@ -16,6 +23,7 @@ SAMPLER_PID=$!
|
||||
|
||||
SINK1="fairmq-ex-copypush-sink"
|
||||
SINK1+=" --id sink1"
|
||||
SINK1+=" --transport $transport"
|
||||
SINK1+=" --verbosity veryhigh"
|
||||
SINK1+=" --control static --color false"
|
||||
SINK1+=" --max-iterations 1"
|
||||
@@ -25,6 +33,7 @@ SINK1_PID=$!
|
||||
|
||||
SINK2="fairmq-ex-copypush-sink"
|
||||
SINK2+=" --id sink2"
|
||||
SINK2+=" --transport $transport"
|
||||
SINK2+=" --verbosity veryhigh"
|
||||
SINK2+=" --control static --color false"
|
||||
SINK2+=" --max-iterations 1"
|
||||
|
@@ -31,8 +31,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multipart.sh.in ${CMA
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multipart.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh)
|
||||
|
||||
add_test(NAME Example-Multipart COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh)
|
||||
set_tests_properties(Example-Multipart PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 2 parts")
|
||||
add_test(NAME Example-Multipart-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh zeromq)
|
||||
set_tests_properties(Example-Multipart-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 2 parts")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-Multipart-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh nanomsg)
|
||||
set_tests_properties(Example-Multipart-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 2 parts")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example-Multipart-shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multipart.sh shmem)
|
||||
set_tests_properties(Example-Multipart-shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received message with 2 parts")
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -2,11 +2,18 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
# setup a trap to kill everything if the test fails/timeouts
|
||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SINK_PID;' TERM
|
||||
|
||||
SAMPLER="fairmq-ex-multipart-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --verbosity veryhigh"
|
||||
SAMPLER+=" --max-iterations 1"
|
||||
SAMPLER+=" --control static --color false"
|
||||
@@ -16,6 +23,7 @@ SAMPLER_PID=$!
|
||||
|
||||
SINK="fairmq-ex-multipart-sink"
|
||||
SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --verbosity veryhigh"
|
||||
SINK+=" --control static --color false"
|
||||
SINK+=" --channel-config name=data,type=pull,method=bind,rateLogging=0,address=tcp://127.0.0.1:5555"
|
||||
|
@@ -36,8 +36,13 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-multiple-channels.sh.
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-multiple-channels.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh)
|
||||
|
||||
add_test(NAME Example-Multiple-Channels COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh)
|
||||
set_tests_properties(Example-Multiple-Channels PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
add_test(NAME Example-Multiple-Channels-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh zeromq)
|
||||
set_tests_properties(Example-Multiple-Channels-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-Multiple-Channels-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-multiple-channels.sh nanomsg)
|
||||
set_tests_properties(Example-Multiple-Channels-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received messages from both sources.")
|
||||
endif()
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -2,12 +2,19 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
# setup a trap to kill everything if the test fails/timeouts
|
||||
trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; kill -TERM $BROADCASTER_PID; wait $SAMPLER_PID; wait $SINK_PID; wait $BROADCASTER_PID;' TERM
|
||||
|
||||
|
||||
SINK="fairmq-ex-multiple-channels-sink"
|
||||
SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --verbosity veryhigh"
|
||||
SINK+=" --max-iterations 1"
|
||||
SINK+=" --control static --color false"
|
||||
@@ -20,6 +27,7 @@ sleep 1
|
||||
|
||||
SAMPLER="fairmq-ex-multiple-channels-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --verbosity veryhigh"
|
||||
SAMPLER+=" --max-iterations 1"
|
||||
SAMPLER+=" --control static --color false"
|
||||
@@ -30,6 +38,7 @@ SAMPLER_PID=$!
|
||||
|
||||
BROADCASTER="fairmq-ex-multiple-channels-broadcaster"
|
||||
BROADCASTER+=" --id broadcaster1"
|
||||
BROADCASTER+=" --transport $transport"
|
||||
BROADCASTER+=" --verbosity veryhigh"
|
||||
BROADCASTER+=" --control static --color false"
|
||||
BROADCASTER+=" --channel-config name=broadcast,type=pub,method=bind,rateLogging=0,address=tcp://*:5005"
|
||||
|
@@ -23,8 +23,6 @@ Sink::Sink()
|
||||
: fMaxIterations(0)
|
||||
, fNumIterations1(0)
|
||||
, fNumIterations2(0)
|
||||
, fReceived1(false)
|
||||
, fReceived2(false)
|
||||
{
|
||||
// register a handler for data arriving on "data" channel
|
||||
OnData("data1", &Sink::HandleData1);
|
||||
|
@@ -36,8 +36,6 @@ class Sink : public FairMQDevice
|
||||
uint64_t fMaxIterations;
|
||||
uint64_t fNumIterations1;
|
||||
uint64_t fNumIterations2;
|
||||
bool fReceived1;
|
||||
bool fReceived2;
|
||||
};
|
||||
|
||||
} // namespace example_multiple_transports
|
||||
|
@@ -24,4 +24,4 @@ SINK+=" --transport shmem"
|
||||
SINK+=" --channel-config name=data1,type=pull,method=connect,address=tcp://127.0.0.1:5555"
|
||||
SINK+=" name=data2,type=pull,method=connect,address=tcp://127.0.0.1:5556,transport=nanomsg"
|
||||
SINK+=" name=ack,type=pub,method=connect,address=tcp://127.0.0.1:5557,transport=zeromq"
|
||||
xterm -geometry 80x30+500+0 -hold -e @EX_BIN_DIR@/$SINK &
|
||||
xterm -geometry 80x30+500+225 -hold -e @EX_BIN_DIR@/$SINK &
|
||||
|
@@ -32,8 +32,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-region.sh.in ${CMAKE_
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-region.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh)
|
||||
|
||||
add_test(NAME Example-Region COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh)
|
||||
set_tests_properties(Example-Region PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
add_test(NAME Example-Region-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh zeromq)
|
||||
set_tests_properties(Example-Region-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-Region-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh nanomsg)
|
||||
set_tests_properties(Example-Region-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example-Region-shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-region.sh shmem)
|
||||
set_tests_properties(Example-Region-shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received ack")
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -38,7 +38,7 @@ void Sampler::InitTask()
|
||||
fRegion = FairMQUnmanagedRegionPtr(NewUnmanagedRegionFor("data",
|
||||
0,
|
||||
10000000,
|
||||
[this](void* data, size_t size, void* hint) { // callback to be called when message buffers no longer needed by transport
|
||||
[this](void* /*data*/, size_t /*size*/, void* /*hint*/) { // callback to be called when message buffers no longer needed by transport
|
||||
--fNumUnackedMsgs;
|
||||
if (fMaxIterations > 0)
|
||||
{
|
||||
|
@@ -2,6 +2,12 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
msgSize="1000000"
|
||||
SESSION="$(@CMAKE_BINARY_DIR@/fairmq/fairmq-uuid-gen -h)"
|
||||
|
||||
@@ -10,23 +16,23 @@ trap 'kill -TERM $SAMPLER_PID; kill -TERM $SINK_PID; wait $SAMPLER_PID; wait $SI
|
||||
|
||||
SAMPLER="fairmq-ex-region-sampler"
|
||||
SAMPLER+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --severity debug"
|
||||
SAMPLER+=" --session $SESSION"
|
||||
SAMPLER+=" --control static --color false"
|
||||
SAMPLER+=" --max-iterations 1"
|
||||
SAMPLER+=" --msg-size $msgSize"
|
||||
SAMPLER+=" --transport shmem"
|
||||
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:7777"
|
||||
@CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
|
||||
SAMPLER_PID=$!
|
||||
|
||||
SINK="fairmq-ex-region-sink"
|
||||
SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --session $SESSION"
|
||||
SINK+=" --verbosity veryhigh"
|
||||
SINK+=" --control static --color false"
|
||||
SINK+=" --max-iterations 1"
|
||||
SINK+=" --transport shmem"
|
||||
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.0.1:7777"
|
||||
@CMAKE_CURRENT_BINARY_DIR@/$SINK &
|
||||
SINK_PID=$!
|
||||
|
@@ -32,8 +32,16 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fairmq-start-ex-req-rep.sh.in ${CMAKE
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-ex-req-rep.sh.in ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh)
|
||||
|
||||
add_test(NAME Example-ReqRep COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh)
|
||||
set_tests_properties(Example-ReqRep PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
add_test(NAME Example-ReqRep-zeromq COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh zeromq)
|
||||
set_tests_properties(Example-ReqRep-zeromq PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
add_test(NAME Example-ReqRep-nanomsg COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh nanomsg)
|
||||
set_tests_properties(Example-ReqRep-nanomsg PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
endif()
|
||||
|
||||
add_test(NAME Example-ReqRep-shmem COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-ex-req-rep.sh shmem)
|
||||
set_tests_properties(Example-ReqRep-shmem PROPERTIES TIMEOUT "30" RUN_SERIAL true PASS_REGULAR_EXPRESSION "Received reply from server: ")
|
||||
|
||||
# install
|
||||
|
||||
|
@@ -2,11 +2,18 @@
|
||||
|
||||
export FAIRMQ_PATH=@FAIRMQ_BIN_DIR@
|
||||
|
||||
transport="zeromq"
|
||||
|
||||
if [[ $1 =~ ^[a-z]+$ ]]; then
|
||||
transport=$1
|
||||
fi
|
||||
|
||||
# setup a trap to kill everything if the test fails/timeouts
|
||||
trap 'kill -TERM $CLIENT_PID; kill -TERM $SERVER_PID; wait $CLIENT_PID; wait $SERVER_PID;' TERM
|
||||
|
||||
CLIENT="fairmq-ex-req-rep-client"
|
||||
CLIENT+=" --id client"
|
||||
CLIENT+=" --transport $transport"
|
||||
CLIENT+=" --verbosity veryhigh"
|
||||
CLIENT+=" --control static --color false"
|
||||
CLIENT+=" --max-iterations 1"
|
||||
@@ -16,6 +23,7 @@ CLIENT_PID=$!
|
||||
|
||||
SERVER="fairmq-ex-req-rep-server"
|
||||
SERVER+=" --id server"
|
||||
SERVER+=" --transport $transport"
|
||||
SERVER+=" --verbosity veryhigh"
|
||||
SERVER+=" --control static --color false"
|
||||
SERVER+=" --max-iterations 1"
|
||||
|
@@ -37,7 +37,7 @@ endif()
|
||||
##########################
|
||||
# libFairMQ header files #
|
||||
##########################
|
||||
set(FAIRMQ_HEADER_FILES
|
||||
set(FAIRMQ_PUBLIC_HEADER_FILES
|
||||
DeviceRunner.h
|
||||
EventManager.h
|
||||
FairMQChannel.h
|
||||
@@ -52,6 +52,21 @@ set(FAIRMQ_HEADER_FILES
|
||||
FairMQTransportFactory.h
|
||||
Tools.h
|
||||
Transports.h
|
||||
options/FairMQProgOptions.h
|
||||
options/FairProgOptions.h
|
||||
Plugin.h
|
||||
PluginManager.h
|
||||
PluginServices.h
|
||||
runFairMQDevice.h
|
||||
tools/CppSTL.h
|
||||
tools/Network.h
|
||||
tools/Process.h
|
||||
tools/Strings.h
|
||||
tools/Unique.h
|
||||
tools/Version.h
|
||||
)
|
||||
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES
|
||||
devices/FairMQBenchmarkSampler.h
|
||||
devices/FairMQMerger.h
|
||||
devices/FairMQMultiplier.h
|
||||
@@ -59,16 +74,10 @@ set(FAIRMQ_HEADER_FILES
|
||||
devices/FairMQSink.h
|
||||
devices/FairMQSplitter.h
|
||||
options/FairMQParser.h
|
||||
options/FairMQProgOptions.h
|
||||
options/FairMQSuboptParser.h
|
||||
options/FairProgOptions.h
|
||||
options/FairProgOptionsHelper.h
|
||||
Plugin.h
|
||||
PluginManager.h
|
||||
PluginServices.h
|
||||
plugins/Builtin.h
|
||||
plugins/Control.h
|
||||
runFairMQDevice.h
|
||||
StateMachine.h
|
||||
shmem/FairMQMessageSHM.h
|
||||
shmem/FairMQPollerSHM.h
|
||||
@@ -79,12 +88,6 @@ set(FAIRMQ_HEADER_FILES
|
||||
shmem/Manager.h
|
||||
shmem/Monitor.h
|
||||
shmem/Region.h
|
||||
tools/CppSTL.h
|
||||
tools/Network.h
|
||||
tools/Process.h
|
||||
tools/Strings.h
|
||||
tools/Unique.h
|
||||
tools/Version.h
|
||||
zeromq/FairMQMessageZMQ.h
|
||||
zeromq/FairMQPollerZMQ.h
|
||||
zeromq/FairMQUnmanagedRegionZMQ.h
|
||||
@@ -93,7 +96,7 @@ set(FAIRMQ_HEADER_FILES
|
||||
)
|
||||
|
||||
if(BUILD_NANOMSG_TRANSPORT)
|
||||
set(FAIRMQ_HEADER_FILES ${FAIRMQ_HEADER_FILES}
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
||||
nanomsg/FairMQMessageNN.h
|
||||
nanomsg/FairMQPollerNN.h
|
||||
nanomsg/FairMQUnmanagedRegionNN.h
|
||||
@@ -103,7 +106,7 @@ if(BUILD_NANOMSG_TRANSPORT)
|
||||
endif()
|
||||
|
||||
if(BUILD_OFI_TRANSPORT)
|
||||
set(FAIRMQ_HEADER_FILES ${FAIRMQ_HEADER_FILES}
|
||||
set(FAIRMQ_PRIVATE_HEADER_FILES ${FAIRMQ_PRIVATE_HEADER_FILES}
|
||||
ofi/Context.h
|
||||
ofi/Message.h
|
||||
ofi/Poller.h
|
||||
@@ -129,12 +132,10 @@ set(FAIRMQ_SOURCE_FILES
|
||||
devices/FairMQMerger.cxx
|
||||
devices/FairMQMultiplier.cxx
|
||||
devices/FairMQProxy.cxx
|
||||
# devices/FairMQSink.cxx
|
||||
devices/FairMQSplitter.cxx
|
||||
options/FairMQParser.cxx
|
||||
options/FairMQProgOptions.cxx
|
||||
options/FairMQSuboptParser.cxx
|
||||
options/FairProgOptions.cxx
|
||||
Plugin.cxx
|
||||
PluginManager.cxx
|
||||
PluginServices.cxx
|
||||
@@ -148,6 +149,9 @@ set(FAIRMQ_SOURCE_FILES
|
||||
shmem/Manager.cxx
|
||||
shmem/Monitor.cxx
|
||||
shmem/Region.cxx
|
||||
tools/Network.cxx
|
||||
tools/Process.cxx
|
||||
tools/Unique.cxx
|
||||
zeromq/FairMQMessageZMQ.cxx
|
||||
zeromq/FairMQPollerZMQ.cxx
|
||||
zeromq/FairMQUnmanagedRegionZMQ.cxx
|
||||
@@ -189,7 +193,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/options/startConfigExample.sh.in ${CM
|
||||
#################################
|
||||
add_library(FairMQ SHARED
|
||||
${FAIRMQ_SOURCE_FILES}
|
||||
${FAIRMQ_HEADER_FILES} # for IDE integration
|
||||
${FAIRMQ_PUBLIC_HEADER_FILES} # for IDE integration
|
||||
${FAIRMQ_PRIVATE_HEADER_FILES} # for IDE integration
|
||||
)
|
||||
|
||||
#######################
|
||||
@@ -290,7 +295,7 @@ install(
|
||||
)
|
||||
|
||||
# preserve relative path and prepend fairmq
|
||||
foreach(HEADER ${FAIRMQ_HEADER_FILES})
|
||||
foreach(HEADER ${FAIRMQ_PUBLIC_HEADER_FILES})
|
||||
get_filename_component(_path ${HEADER} DIRECTORY)
|
||||
file(TO_CMAKE_PATH ${PROJECT_INSTALL_INCDIR}/${_path} _destination)
|
||||
install(FILES ${HEADER}
|
||||
|
@@ -56,6 +56,8 @@ auto DeviceRunner::Run() -> int
|
||||
return 1;
|
||||
}
|
||||
|
||||
fDevice->SetRawCmdLineArgs(fRawCmdLineArgs);
|
||||
|
||||
// Handle --print-channels
|
||||
fDevice->RegisterChannelEndpoints();
|
||||
if (fConfig.Count("print-channels"))
|
||||
|
@@ -28,7 +28,7 @@ FairMQChannel::FairMQChannel()
|
||||
, fType("unspecified")
|
||||
, fMethod("unspecified")
|
||||
, fAddress("unspecified")
|
||||
, fTransport("default")
|
||||
, fTransportType(fair::mq::Transport::DEFAULT)
|
||||
, fSndBufSize(1000)
|
||||
, fRcvBufSize(1000)
|
||||
, fSndKernelSize(0)
|
||||
@@ -36,7 +36,6 @@ FairMQChannel::FairMQChannel()
|
||||
, fRateLogging(1)
|
||||
, fName("")
|
||||
, fIsValid(false)
|
||||
, fTransportType(FairMQ::Transport::DEFAULT)
|
||||
, fTransportFactory(nullptr)
|
||||
, fMultipart(false)
|
||||
, fModified(true)
|
||||
@@ -49,7 +48,7 @@ FairMQChannel::FairMQChannel(const string& type, const string& method, const str
|
||||
, fType(type)
|
||||
, fMethod(method)
|
||||
, fAddress(address)
|
||||
, fTransport("default")
|
||||
, fTransportType(fair::mq::Transport::DEFAULT)
|
||||
, fSndBufSize(1000)
|
||||
, fRcvBufSize(1000)
|
||||
, fSndKernelSize(0)
|
||||
@@ -57,7 +56,6 @@ FairMQChannel::FairMQChannel(const string& type, const string& method, const str
|
||||
, fRateLogging(1)
|
||||
, fName("")
|
||||
, fIsValid(false)
|
||||
, fTransportType(FairMQ::Transport::DEFAULT)
|
||||
, fTransportFactory(nullptr)
|
||||
, fMultipart(false)
|
||||
, fModified(true)
|
||||
@@ -70,7 +68,7 @@ FairMQChannel::FairMQChannel(const string& name, const string& type, std::shared
|
||||
, fType(type)
|
||||
, fMethod("unspecified")
|
||||
, fAddress("unspecified")
|
||||
, fTransport("default") // TODO refactor, either use string representation or enum type
|
||||
, fTransportType(factory->GetType())
|
||||
, fSndBufSize(1000)
|
||||
, fRcvBufSize(1000)
|
||||
, fSndKernelSize(0)
|
||||
@@ -78,7 +76,6 @@ FairMQChannel::FairMQChannel(const string& name, const string& type, std::shared
|
||||
, fRateLogging(1)
|
||||
, fName(name)
|
||||
, fIsValid(false)
|
||||
, fTransportType(factory->GetType())
|
||||
, fTransportFactory(factory)
|
||||
, fMultipart(false)
|
||||
, fModified(true)
|
||||
@@ -91,7 +88,7 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan)
|
||||
, fType(chan.fType)
|
||||
, fMethod(chan.fMethod)
|
||||
, fAddress(chan.fAddress)
|
||||
, fTransport(chan.fTransport)
|
||||
, fTransportType(chan.fTransportType)
|
||||
, fSndBufSize(chan.fSndBufSize)
|
||||
, fRcvBufSize(chan.fRcvBufSize)
|
||||
, fSndKernelSize(chan.fSndKernelSize)
|
||||
@@ -99,7 +96,6 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan)
|
||||
, fRateLogging(chan.fRateLogging)
|
||||
, fName(chan.fName)
|
||||
, fIsValid(false)
|
||||
, fTransportType(FairMQ::Transport::DEFAULT)
|
||||
, fTransportFactory(nullptr)
|
||||
, fMultipart(chan.fMultipart)
|
||||
, fModified(chan.fModified)
|
||||
@@ -111,7 +107,6 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||
fType = chan.fType;
|
||||
fMethod = chan.fMethod;
|
||||
fAddress = chan.fAddress;
|
||||
fTransport = chan.fTransport;
|
||||
fSndBufSize = chan.fSndBufSize;
|
||||
fRcvBufSize = chan.fRcvBufSize;
|
||||
fSndKernelSize = chan.fSndKernelSize;
|
||||
@@ -120,7 +115,7 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
|
||||
fSocket = nullptr;
|
||||
fName = chan.fName;
|
||||
fIsValid = false;
|
||||
fTransportType = FairMQ::Transport::DEFAULT;
|
||||
fTransportType = chan.fTransportType;
|
||||
fTransportFactory = nullptr;
|
||||
|
||||
return *this;
|
||||
@@ -194,16 +189,16 @@ string FairMQChannel::GetAddress() const
|
||||
}
|
||||
}
|
||||
|
||||
string FairMQChannel::GetTransport() const
|
||||
string FairMQChannel::GetTransportName() const
|
||||
{
|
||||
try
|
||||
{
|
||||
unique_lock<mutex> lock(fChannelMutex);
|
||||
return fTransport;
|
||||
return fair::mq::TransportNames.at(fTransportType);
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetTransport: " << e.what();
|
||||
LOG(error) << "Exception caught in FairMQChannel::GetTransportName: " << e.what();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -332,7 +327,7 @@ void FairMQChannel::UpdateTransport(const string& transport)
|
||||
{
|
||||
unique_lock<mutex> lock(fChannelMutex);
|
||||
fIsValid = false;
|
||||
fTransport = transport;
|
||||
fTransportType = fair::mq::TransportTypes.at(transport);
|
||||
fModified = true;
|
||||
}
|
||||
catch (exception& e)
|
||||
@@ -504,7 +499,7 @@ bool FairMQChannel::ValidateChannel()
|
||||
else
|
||||
{
|
||||
vector<string> endpoints;
|
||||
boost::algorithm::split(endpoints, fAddress, boost::algorithm::is_any_of(","));
|
||||
boost::algorithm::split(endpoints, fAddress, boost::algorithm::is_any_of(";"));
|
||||
for (const auto endpoint : endpoints)
|
||||
{
|
||||
string address;
|
||||
@@ -586,17 +581,6 @@ bool FairMQChannel::ValidateChannel()
|
||||
}
|
||||
}
|
||||
|
||||
// validate channel transport
|
||||
// const string channelTransportNames[] = { "default", "zeromq", "nanomsg", "shmem" };
|
||||
// const set<string> channelTransports(channelTransportNames, channelTransportNames + sizeof(channelTransportNames) / sizeof(string));
|
||||
if (FairMQ::TransportTypes.find(fTransport) == FairMQ::TransportTypes.end())
|
||||
{
|
||||
ss << "INVALID";
|
||||
LOG(debug) << ss.str();
|
||||
LOG(error) << "Invalid channel transport: \"" << fTransport << "\"";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// validate socket buffer size for sending
|
||||
if (fSndBufSize < 0)
|
||||
{
|
||||
@@ -669,13 +653,13 @@ void FairMQChannel::ResetChannel()
|
||||
|
||||
int FairMQChannel::Send(unique_ptr<FairMQMessage>& msg) const
|
||||
{
|
||||
CheckCompatibility(msg);
|
||||
CheckSendCompatibility(msg);
|
||||
return fSocket->Send(msg);
|
||||
}
|
||||
|
||||
int FairMQChannel::Receive(unique_ptr<FairMQMessage>& msg) const
|
||||
{
|
||||
CheckCompatibility(msg);
|
||||
CheckReceiveCompatibility(msg);
|
||||
return fSocket->Receive(msg);
|
||||
}
|
||||
|
||||
@@ -691,25 +675,25 @@ int FairMQChannel::Receive(unique_ptr<FairMQMessage>& msg, int rcvTimeoutInMs) c
|
||||
|
||||
int FairMQChannel::SendAsync(unique_ptr<FairMQMessage>& msg) const
|
||||
{
|
||||
CheckCompatibility(msg);
|
||||
CheckSendCompatibility(msg);
|
||||
return fSocket->TrySend(msg);
|
||||
}
|
||||
|
||||
int FairMQChannel::ReceiveAsync(unique_ptr<FairMQMessage>& msg) const
|
||||
{
|
||||
CheckCompatibility(msg);
|
||||
CheckReceiveCompatibility(msg);
|
||||
return fSocket->TryReceive(msg);
|
||||
}
|
||||
|
||||
int64_t FairMQChannel::Send(vector<unique_ptr<FairMQMessage>>& msgVec) const
|
||||
{
|
||||
CheckCompatibility(msgVec);
|
||||
CheckSendCompatibility(msgVec);
|
||||
return fSocket->Send(msgVec);
|
||||
}
|
||||
|
||||
int64_t FairMQChannel::Receive(vector<unique_ptr<FairMQMessage>>& msgVec) const
|
||||
{
|
||||
CheckCompatibility(msgVec);
|
||||
CheckReceiveCompatibility(msgVec);
|
||||
return fSocket->Receive(msgVec);
|
||||
}
|
||||
|
||||
@@ -725,7 +709,7 @@ int64_t FairMQChannel::Receive(vector<unique_ptr<FairMQMessage>>& msgVec, int rc
|
||||
|
||||
int64_t FairMQChannel::SendAsync(vector<unique_ptr<FairMQMessage>>& msgVec) const
|
||||
{
|
||||
CheckCompatibility(msgVec);
|
||||
CheckSendCompatibility(msgVec);
|
||||
return fSocket->TrySend(msgVec);
|
||||
}
|
||||
|
||||
@@ -736,7 +720,7 @@ int64_t FairMQChannel::SendAsync(vector<unique_ptr<FairMQMessage>>& msgVec) cons
|
||||
/// In case of errors, returns -1.
|
||||
int64_t FairMQChannel::ReceiveAsync(vector<unique_ptr<FairMQMessage>>& msgVec) const
|
||||
{
|
||||
CheckCompatibility(msgVec);
|
||||
CheckReceiveCompatibility(msgVec);
|
||||
return fSocket->TryReceive(msgVec);
|
||||
}
|
||||
|
||||
@@ -764,44 +748,58 @@ unsigned long FairMQChannel::GetMessagesRx() const
|
||||
return fSocket->GetMessagesRx();
|
||||
}
|
||||
|
||||
bool FairMQChannel::CheckCompatibility(unique_ptr<FairMQMessage>& msg) const
|
||||
void FairMQChannel::CheckSendCompatibility(FairMQMessagePtr& msg) const
|
||||
{
|
||||
if (fTransportType == msg->GetType())
|
||||
if (fTransportType != msg->GetType())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// LOG(warn) << "Channel type does not match message type. Copying...";
|
||||
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage(msg->GetSize()));
|
||||
memcpy(msgCopy->GetData(), msg->GetData(), msg->GetSize());
|
||||
msg = move(msgCopy);
|
||||
return false;
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
FairMQMessagePtr msgWrapper(NewMessage(msg->GetData(),
|
||||
msg->GetSize(),
|
||||
[](void* /*data*/, void* msg) { delete static_cast<FairMQMessage*>(msg); },
|
||||
msg.get()
|
||||
));
|
||||
msg.release();
|
||||
msg = move(msgWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
bool FairMQChannel::CheckCompatibility(vector<unique_ptr<FairMQMessage>>& msgVec) const
|
||||
void FairMQChannel::CheckSendCompatibility(vector<FairMQMessagePtr>& msgVec) const
|
||||
{
|
||||
bool match = true;
|
||||
|
||||
if (msgVec.size() > 0)
|
||||
for (auto& msg : msgVec)
|
||||
{
|
||||
for (unsigned int i = 0; i < msgVec.size(); ++i)
|
||||
if (fTransportType != msg->GetType())
|
||||
{
|
||||
if (fTransportType != msgVec.at(i)->GetType())
|
||||
{
|
||||
// LOG(warn) << "Channel type does not match message type. Copying...";
|
||||
FairMQMessagePtr newMsg(fTransportFactory->CreateMessage(msgVec[i]->GetSize()));
|
||||
memcpy(newMsg->GetData(), msgVec[i]->GetData(), msgVec[i]->GetSize());
|
||||
msgVec[i] = move(newMsg);
|
||||
match = false;
|
||||
}
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
FairMQMessagePtr msgWrapper(NewMessage(msg->GetData(),
|
||||
msg->GetSize(),
|
||||
[](void* /*data*/, void* msg) { delete static_cast<FairMQMessage*>(msg); },
|
||||
msg.get()
|
||||
));
|
||||
msg.release();
|
||||
msg = move(msgWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQChannel::CheckReceiveCompatibility(FairMQMessagePtr& msg) const
|
||||
{
|
||||
if (fTransportType != msg->GetType())
|
||||
{
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
FairMQMessagePtr newMsg(NewMessage());
|
||||
msg = move(newMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQChannel::CheckReceiveCompatibility(vector<FairMQMessagePtr>& msgVec) const
|
||||
{
|
||||
for (auto& msg : msgVec)
|
||||
{
|
||||
if (fTransportType != msg->GetType())
|
||||
{
|
||||
// LOG(debug) << "Channel type does not match message type. Creating wrapper";
|
||||
FairMQMessagePtr newMsg(NewMessage());
|
||||
msg = move(newMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <fairmq/Transports.h>
|
||||
#include <FairMQLogger.h>
|
||||
#include <FairMQParts.h>
|
||||
#include <FairMQMessage.h>
|
||||
|
||||
class FairMQChannel
|
||||
{
|
||||
@@ -92,7 +93,7 @@ class FairMQChannel
|
||||
|
||||
/// Get channel transport ("default", "zeromq", "nanomsg" or "shmem")
|
||||
/// @return Returns channel transport (e.g. "default", "zeromq", "nanomsg" or "shmem")
|
||||
std::string GetTransport() const;
|
||||
std::string GetTransportName() const;
|
||||
|
||||
/// Get socket send buffer size (in number of messages)
|
||||
/// @return Returns socket send buffer size (in number of messages)
|
||||
@@ -165,8 +166,8 @@ class FairMQChannel
|
||||
/// Resets the channel (requires validation to be used again).
|
||||
void ResetChannel();
|
||||
|
||||
int Send(std::unique_ptr<FairMQMessage>& msg) const;
|
||||
int Receive(std::unique_ptr<FairMQMessage>& msg) const;
|
||||
int Send(FairMQMessagePtr& msg) const;
|
||||
int Receive(FairMQMessagePtr& msg) const;
|
||||
|
||||
/// Sends a message to the socket queue.
|
||||
/// @details Send method attempts to send a message by
|
||||
@@ -176,7 +177,7 @@ class FairMQChannel
|
||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out.
|
||||
/// In case of errors, returns -1.
|
||||
int Send(std::unique_ptr<FairMQMessage>& msg, int sndTimeoutInMs) const;
|
||||
int Send(FairMQMessagePtr& msg, int sndTimeoutInMs) const;
|
||||
|
||||
/// Receives a message from the socket queue.
|
||||
/// @details Receive method attempts to receive a message from the input queue.
|
||||
@@ -185,7 +186,7 @@ class FairMQChannel
|
||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
||||
/// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out.
|
||||
/// In case of errors, returns -1.
|
||||
int Receive(std::unique_ptr<FairMQMessage>& msg, int rcvTimeoutInMs) const;
|
||||
int Receive(FairMQMessagePtr& msg, int rcvTimeoutInMs) const;
|
||||
|
||||
/// Sends a message in non-blocking mode.
|
||||
/// @details SendAsync method attempts to send a message without blocking by
|
||||
@@ -195,31 +196,31 @@ class FairMQChannel
|
||||
/// @return Number of bytes that have been queued. If queueing failed due to
|
||||
/// full queue or no connected peers (when binding), returns -2.
|
||||
/// In case of errors, returns -1.
|
||||
int SendAsync(std::unique_ptr<FairMQMessage>& msg) const;
|
||||
int SendAsync(FairMQMessagePtr& msg) const;
|
||||
|
||||
/// Receives a message in non-blocking mode.
|
||||
///
|
||||
/// @param msg Constant reference of unique_ptr to a FairMQMessage
|
||||
/// @return Number of bytes that have been received. If queue is empty, returns -2.
|
||||
/// In case of errors, returns -1.
|
||||
int ReceiveAsync(std::unique_ptr<FairMQMessage>& msg) const;
|
||||
int ReceiveAsync(FairMQMessagePtr& msg) const;
|
||||
|
||||
int64_t Send(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const;
|
||||
int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const;
|
||||
int64_t Send(std::vector<FairMQMessagePtr>& msgVec) const;
|
||||
int64_t Receive(std::vector<FairMQMessagePtr>& msgVec) const;
|
||||
|
||||
/// Send a vector of messages
|
||||
///
|
||||
/// @param msgVec message vector reference
|
||||
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out.
|
||||
/// In case of errors, returns -1.
|
||||
int64_t Send(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int sndTimeoutInMs) const;
|
||||
int64_t Send(std::vector<FairMQMessagePtr>& msgVec, int sndTimeoutInMs) const;
|
||||
|
||||
/// Receive a vector of messages
|
||||
///
|
||||
/// @param msgVec message vector reference
|
||||
/// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out.
|
||||
/// In case of errors, returns -1.
|
||||
int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int rcvTimeoutInMs) const;
|
||||
int64_t Receive(std::vector<FairMQMessagePtr>& msgVec, int rcvTimeoutInMs) const;
|
||||
|
||||
/// Sends a vector of message in non-blocking mode.
|
||||
/// @details SendAsync method attempts to send a vector of messages without blocking by
|
||||
@@ -228,14 +229,14 @@ class FairMQChannel
|
||||
/// @param msgVec message vector reference
|
||||
/// @return Number of bytes that have been queued. If queueing failed due to
|
||||
/// full queue or no connected peers (when binding), returns -2. In case of errors, returns -1.
|
||||
int64_t SendAsync(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const;
|
||||
int64_t SendAsync(std::vector<FairMQMessagePtr>& msgVec) const;
|
||||
|
||||
/// Receives a vector of messages in non-blocking mode.
|
||||
///
|
||||
/// @param msgVec message vector reference
|
||||
/// @return Number of bytes that have been received. If queue is empty, returns -2.
|
||||
/// In case of errors, returns -1.
|
||||
int64_t ReceiveAsync(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const;
|
||||
int64_t ReceiveAsync(std::vector<FairMQMessagePtr>& msgVec) const;
|
||||
|
||||
int64_t Send(FairMQParts& parts) const
|
||||
{
|
||||
@@ -301,7 +302,7 @@ class FairMQChannel
|
||||
std::string fType;
|
||||
std::string fMethod;
|
||||
std::string fAddress;
|
||||
std::string fTransport;
|
||||
fair::mq::Transport fTransportType;
|
||||
int fSndBufSize;
|
||||
int fRcvBufSize;
|
||||
int fSndKernelSize;
|
||||
@@ -311,11 +312,12 @@ class FairMQChannel
|
||||
std::string fName;
|
||||
std::atomic<bool> fIsValid;
|
||||
|
||||
FairMQ::Transport fTransportType;
|
||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory;
|
||||
|
||||
bool CheckCompatibility(std::unique_ptr<FairMQMessage>& msg) const;
|
||||
bool CheckCompatibility(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const;
|
||||
void CheckSendCompatibility(FairMQMessagePtr& msg) const;
|
||||
void CheckSendCompatibility(std::vector<FairMQMessagePtr>& msgVec) const;
|
||||
void CheckReceiveCompatibility(FairMQMessagePtr& msg) const;
|
||||
void CheckReceiveCompatibility(std::vector<FairMQMessagePtr>& msgVec) const;
|
||||
|
||||
void InitTransport(std::shared_ptr<FairMQTransportFactory> factory);
|
||||
|
||||
|
@@ -26,9 +26,12 @@
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <algorithm> // std::max
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
FairMQDevice::FairMQDevice()
|
||||
: fTransportFactory(nullptr)
|
||||
, fTransports()
|
||||
@@ -42,7 +45,7 @@ FairMQDevice::FairMQDevice()
|
||||
, fPortRangeMin(22000)
|
||||
, fPortRangeMax(32000)
|
||||
, fNetworkInterface()
|
||||
, fDefaultTransport("default")
|
||||
, fDefaultTransportType(fair::mq::Transport::DEFAULT)
|
||||
, fInitializationTimeoutInS(120)
|
||||
, fDataCallbacks(false)
|
||||
, fMsgInputs()
|
||||
@@ -56,6 +59,7 @@ FairMQDevice::FairMQDevice()
|
||||
, fVersion({0, 0, 0})
|
||||
, fRate(0.)
|
||||
, fLastTime(0)
|
||||
, fRawCmdLineArgs()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -72,7 +76,7 @@ FairMQDevice::FairMQDevice(const fair::mq::tools::Version version)
|
||||
, fPortRangeMin(22000)
|
||||
, fPortRangeMax(32000)
|
||||
, fNetworkInterface()
|
||||
, fDefaultTransport("default")
|
||||
, fDefaultTransportType(fair::mq::Transport::DEFAULT)
|
||||
, fInitializationTimeoutInS(120)
|
||||
, fDataCallbacks(false)
|
||||
, fMsgInputs()
|
||||
@@ -86,6 +90,7 @@ FairMQDevice::FairMQDevice(const fair::mq::tools::Version version)
|
||||
, fVersion(version)
|
||||
, fRate(0.)
|
||||
, fLastTime(0)
|
||||
, fRawCmdLineArgs()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -143,7 +148,8 @@ void FairMQDevice::InitWrapper()
|
||||
else
|
||||
{
|
||||
LOG(error) << "Cannot update configuration. Socket method (bind/connect) not specified.";
|
||||
throw runtime_error("Cannot update configuration. Socket method (bind/connect) not specified.");
|
||||
ChangeState(ERROR_FOUND);
|
||||
// throw runtime_error("Cannot update configuration. Socket method (bind/connect) not specified.");
|
||||
}
|
||||
// }
|
||||
}
|
||||
@@ -156,7 +162,8 @@ void FairMQDevice::InitWrapper()
|
||||
if (uninitializedBindingChannels.size() > 0)
|
||||
{
|
||||
LOG(error) << uninitializedBindingChannels.size() << " of the binding channels could not initialize. Initial configuration incomplete.";
|
||||
throw runtime_error(fair::mq::tools::ToString(uninitializedBindingChannels.size(), " of the binding channels could not initialize. Initial configuration incomplete."));
|
||||
ChangeState(ERROR_FOUND);
|
||||
// throw runtime_error(fair::mq::tools::ToString(uninitializedBindingChannels.size(), " of the binding channels could not initialize. Initial configuration incomplete."));
|
||||
}
|
||||
|
||||
CallStateChangeCallbacks(INITIALIZING_DEVICE);
|
||||
@@ -195,7 +202,8 @@ void FairMQDevice::InitWrapper()
|
||||
if (numAttempts++ > maxAttempts)
|
||||
{
|
||||
LOG(error) << "could not connect all channels after " << fInitializationTimeoutInS << " attempts";
|
||||
throw runtime_error(fair::mq::tools::ToString("could not connect all channels after ", fInitializationTimeoutInS, " attempts"));
|
||||
ChangeState(ERROR_FOUND);
|
||||
// throw runtime_error(fair::mq::tools::ToString("could not connect all channels after ", fInitializationTimeoutInS, " attempts"));
|
||||
}
|
||||
|
||||
AttachChannels(uninitializedConnectingChannels);
|
||||
@@ -246,15 +254,15 @@ bool FairMQDevice::AttachChannel(FairMQChannel& ch)
|
||||
{
|
||||
if (!ch.fTransportFactory)
|
||||
{
|
||||
if (ch.fTransport == "default" || ch.fTransport == fDefaultTransport)
|
||||
if (ch.fTransportType == fair::mq::Transport::DEFAULT || ch.fTransportType == fTransportFactory->GetType())
|
||||
{
|
||||
LOG(debug) << ch.fName << ": using default transport";
|
||||
ch.InitTransport(fTransportFactory);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(debug) << ch.fName << ": channel transport (" << fDefaultTransport << ") overriden to " << ch.fTransport;
|
||||
ch.InitTransport(AddTransport(ch.fTransport));
|
||||
LOG(debug) << ch.fName << ": channel transport (" << fair::mq::TransportNames.at(fDefaultTransportType) << ") overriden to " << fair::mq::TransportNames.at(ch.fTransportType);
|
||||
ch.InitTransport(AddTransport(ch.fTransportType));
|
||||
}
|
||||
ch.fTransportType = ch.fTransportFactory->GetType();
|
||||
}
|
||||
@@ -266,7 +274,15 @@ bool FairMQDevice::AttachChannel(FairMQChannel& ch)
|
||||
//(re-)init socket
|
||||
if (!ch.fSocket)
|
||||
{
|
||||
ch.fSocket = ch.fTransportFactory->CreateSocket(ch.fType, ch.fName);
|
||||
try
|
||||
{
|
||||
ch.fSocket = ch.fTransportFactory->CreateSocket(ch.fType, ch.fName);
|
||||
}
|
||||
catch (fair::mq::SocketError& se)
|
||||
{
|
||||
LOG(error) << se.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set high water marks
|
||||
@@ -500,7 +516,7 @@ void FairMQDevice::RunWrapper()
|
||||
while (CheckCurrentState(RUNNING) && ConditionalRun())
|
||||
{
|
||||
if (fRate > 0.001) {
|
||||
auto timespan = chrono::duration_cast<TimeScale>(Clock::now() - reftime).count() - fLastTime;
|
||||
auto timespan = static_cast<TimeScale::rep>(chrono::duration_cast<TimeScale>(Clock::now() - reftime).count() - fLastTime);
|
||||
if (timespan < period) {
|
||||
TimeScale sleepfor(period - timespan);
|
||||
this_thread::sleep_for(sleepfor);
|
||||
@@ -555,10 +571,10 @@ void FairMQDevice::HandleMultipleChannelInput()
|
||||
fMultitransportInputs.clear();
|
||||
for (const auto& k : fInputChannelKeys)
|
||||
{
|
||||
FairMQ::Transport t = fChannels.at(k).at(0).fTransportType;
|
||||
fair::mq::Transport t = fChannels.at(k).at(0).fTransportType;
|
||||
if (fMultitransportInputs.find(t) == fMultitransportInputs.end())
|
||||
{
|
||||
fMultitransportInputs.insert(pair<FairMQ::Transport, vector<string>>(t, vector<string>()));
|
||||
fMultitransportInputs.insert(pair<fair::mq::Transport, vector<string>>(t, vector<string>()));
|
||||
fMultitransportInputs.at(t).push_back(k);
|
||||
}
|
||||
else
|
||||
@@ -760,24 +776,24 @@ void FairMQDevice::Pause()
|
||||
LOG(debug) << "Unpausing";
|
||||
}
|
||||
|
||||
shared_ptr<FairMQTransportFactory> FairMQDevice::AddTransport(const string& transport)
|
||||
shared_ptr<FairMQTransportFactory> FairMQDevice::AddTransport(const fair::mq::Transport transport)
|
||||
{
|
||||
auto i = fTransports.find(FairMQ::TransportTypes.at(transport));
|
||||
auto i = fTransports.find(transport);
|
||||
|
||||
if (i == fTransports.end())
|
||||
{
|
||||
auto tr = FairMQTransportFactory::CreateTransportFactory(transport, fId, fConfig);
|
||||
auto tr = FairMQTransportFactory::CreateTransportFactory(fair::mq::TransportNames.at(transport), fId, fConfig);
|
||||
|
||||
LOG(debug) << "Adding '" << transport << "' transport to the device.";
|
||||
LOG(debug) << "Adding '" << fair::mq::TransportNames.at(transport) << "' transport to the device.";
|
||||
|
||||
pair<FairMQ::Transport, shared_ptr<FairMQTransportFactory>> trPair(FairMQ::TransportTypes.at(transport), tr);
|
||||
pair<fair::mq::Transport, shared_ptr<FairMQTransportFactory>> trPair(transport, tr);
|
||||
fTransports.insert(trPair);
|
||||
|
||||
return tr;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(debug) << "Reusing existing '" << transport << "' transport.";
|
||||
LOG(debug) << "Reusing existing '" << fair::mq::TransportNames.at(transport) << "' transport.";
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
@@ -804,7 +820,11 @@ void FairMQDevice::CreateOwnConfig()
|
||||
fNumIoThreads = fConfig->GetValue<int>("io-threads");
|
||||
fInitializationTimeoutInS = fConfig->GetValue<int>("initialization-timeout");
|
||||
fRate = fConfig->GetValue<float>("rate");
|
||||
fDefaultTransport = fConfig->GetValue<string>("transport");
|
||||
try {
|
||||
fDefaultTransportType = fair::mq::TransportTypes.at(fConfig->GetValue<string>("transport"));
|
||||
} catch(const exception& e) {
|
||||
LOG(error) << "invalid transport type provided: " << fConfig->GetValue<string>("transport");
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQDevice::SetTransport(const string& transport)
|
||||
@@ -819,7 +839,7 @@ void FairMQDevice::SetTransport(const string& transport)
|
||||
if (fTransports.empty())
|
||||
{
|
||||
LOG(debug) << "Requesting '" << transport << "' as default transport for the device";
|
||||
fTransportFactory = AddTransport(transport);
|
||||
fTransportFactory = AddTransport(fair::mq::TransportTypes.at(transport));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -832,20 +852,24 @@ void FairMQDevice::SetConfig(FairMQProgOptions& config)
|
||||
{
|
||||
fExternalConfig = true;
|
||||
fConfig = &config;
|
||||
for (auto& c : config.GetFairMQMap())
|
||||
for (auto& c : fConfig->GetFairMQMap())
|
||||
{
|
||||
if (!fChannels.insert(c).second)
|
||||
{
|
||||
LOG(warn) << "did not insert channel '" << c.first << "', it is already in the device.";
|
||||
}
|
||||
}
|
||||
fId = config.GetValue<string>("id");
|
||||
fNetworkInterface = config.GetValue<string>("network-interface");
|
||||
fNumIoThreads = config.GetValue<int>("io-threads");
|
||||
fInitializationTimeoutInS = config.GetValue<int>("initialization-timeout");
|
||||
fId = fConfig->GetValue<string>("id");
|
||||
fNetworkInterface = fConfig->GetValue<string>("network-interface");
|
||||
fNumIoThreads = fConfig->GetValue<int>("io-threads");
|
||||
fInitializationTimeoutInS = fConfig->GetValue<int>("initialization-timeout");
|
||||
fRate = fConfig->GetValue<float>("rate");
|
||||
fDefaultTransport = config.GetValue<string>("transport");
|
||||
SetTransport(fDefaultTransport);
|
||||
try {
|
||||
fDefaultTransportType = fair::mq::TransportTypes.at(fConfig->GetValue<string>("transport"));
|
||||
} catch(const exception& e) {
|
||||
LOG(error) << "invalid transport type provided: " << fConfig->GetValue<string>("transport");
|
||||
}
|
||||
SetTransport(fConfig->GetValue<string>("transport"));
|
||||
}
|
||||
|
||||
void FairMQDevice::LogSocketRates()
|
||||
@@ -860,6 +884,8 @@ void FairMQDevice::LogSocketRates()
|
||||
vector<int> logIntervals;
|
||||
vector<int> intervalCounters;
|
||||
|
||||
size_t chanNameLen = 0;
|
||||
|
||||
// iterate over the channels map
|
||||
for (const auto& mi : fChannels)
|
||||
{
|
||||
@@ -872,6 +898,7 @@ void FairMQDevice::LogSocketRates()
|
||||
logIntervals.push_back(vi->fRateLogging);
|
||||
intervalCounters.push_back(0);
|
||||
filteredChannelNames.push_back(fair::mq::tools::ToString(mi.first, "[", vi - (mi.second).begin(), "]"));
|
||||
chanNameLen = max(chanNameLen, filteredChannelNames.back().length());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -940,9 +967,9 @@ void FairMQDevice::LogSocketRates()
|
||||
bytesOut.at(i) = bytesOutNew.at(i);
|
||||
msgOut.at(i) = msgOutNew.at(i);
|
||||
|
||||
LOG(info) << filteredChannelNames.at(i) << ": "
|
||||
<< "in: " << msgPerSecIn.at(i) << " (" << mbPerSecIn.at(i) << " MB) "
|
||||
<< "out: " << msgPerSecOut.at(i) << " (" << mbPerSecOut.at(i) << " MB)";
|
||||
LOG(info) << setw(chanNameLen) << filteredChannelNames.at(i) << ": "
|
||||
<< "in: " << msgPerSecIn.at(i) << " (" << mbPerSecIn.at(i) << " MB) "
|
||||
<< "out: " << msgPerSecOut.at(i) << " (" << mbPerSecOut.at(i) << " MB)";
|
||||
}
|
||||
|
||||
++i;
|
||||
|
@@ -196,7 +196,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
/// @brief Getter for default transport factory
|
||||
auto Transport() const -> const FairMQTransportFactory*
|
||||
{
|
||||
return fTransports.at(fair::mq::TransportTypes[GetDefaultTransport()]).get();
|
||||
return fTransportFactory.get();
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@@ -208,7 +208,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
template<typename... Args>
|
||||
FairMQMessagePtr NewMessageFor(const std::string& channel, int index, Args&&... args) const
|
||||
{
|
||||
return fChannels.at(channel).at(index).Transport()->CreateMessage(std::forward<Args>(args)...);
|
||||
return fChannels.at(channel).at(index).NewMessage(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -253,7 +253,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
// if more than one channel provided, check compatibility
|
||||
if (chans.size() > 1)
|
||||
{
|
||||
FairMQ::Transport type = fChannels.at(chans.at(0)).at(0).Transport()->GetType();
|
||||
fair::mq::Transport type = fChannels.at(chans.at(0)).at(0).Transport()->GetType();
|
||||
|
||||
for (unsigned int i = 1; i < chans.size(); ++i)
|
||||
{
|
||||
@@ -273,7 +273,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
// if more than one channel provided, check compatibility
|
||||
if (channels.size() > 1)
|
||||
{
|
||||
FairMQ::Transport type = channels.at(0)->Transport()->GetType();
|
||||
fair::mq::Transport type = channels.at(0)->Transport()->GetType();
|
||||
|
||||
for (unsigned int i = 1; i < channels.size(); ++i)
|
||||
{
|
||||
@@ -293,7 +293,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
|
||||
/// Adds a transport to the device if it doesn't exist
|
||||
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
|
||||
std::shared_ptr<FairMQTransportFactory> AddTransport(const std::string& transport);
|
||||
std::shared_ptr<FairMQTransportFactory> AddTransport(const fair::mq::Transport transport);
|
||||
/// Sets the default transport for the device
|
||||
/// @param transport Transport string ("zeromq"/"nanomsg"/"shmem")
|
||||
void SetTransport(const std::string& transport = "zeromq");
|
||||
@@ -407,15 +407,18 @@ class FairMQDevice : public FairMQStateMachine
|
||||
void SetNetworkInterface(const std::string& networkInterface) { fNetworkInterface = networkInterface; }
|
||||
std::string GetNetworkInterface() const { return fNetworkInterface; }
|
||||
|
||||
void SetDefaultTransport(const std::string& defaultTransport) { fDefaultTransport = defaultTransport; }
|
||||
std::string GetDefaultTransport() const { return fDefaultTransport; }
|
||||
void SetDefaultTransport(const std::string& name) { fDefaultTransportType = fair::mq::TransportTypes.at(name); }
|
||||
std::string GetDefaultTransport() const { return fair::mq::TransportNames.at(fDefaultTransportType); }
|
||||
|
||||
void SetInitializationTimeoutInS(int initializationTimeoutInS) { fInitializationTimeoutInS = initializationTimeoutInS; }
|
||||
int GetInitializationTimeoutInS() const { return fInitializationTimeoutInS; }
|
||||
|
||||
void SetRawCmdLineArgs(const std::vector<std::string>& args) { fRawCmdLineArgs = args; }
|
||||
std::vector<std::string> GetRawCmdLineArgs() const { return fRawCmdLineArgs; }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory; ///< Transport factory
|
||||
std::unordered_map<FairMQ::Transport, std::shared_ptr<FairMQTransportFactory>> fTransports; ///< Container for transports
|
||||
std::shared_ptr<FairMQTransportFactory> fTransportFactory; ///< Default transport factory
|
||||
std::unordered_map<fair::mq::Transport, std::shared_ptr<FairMQTransportFactory>> fTransports; ///< Container for transports
|
||||
|
||||
public:
|
||||
std::unordered_map<std::string, std::vector<FairMQChannel>> fChannels; ///< Device channels
|
||||
@@ -472,7 +475,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
int fPortRangeMax; ///< Maximum value for the port range (if dynamic)
|
||||
|
||||
std::string fNetworkInterface; ///< Network interface to use for dynamic binding
|
||||
std::string fDefaultTransport; ///< Default transport for the device
|
||||
fair::mq::Transport fDefaultTransportType; ///< Default transport for the device
|
||||
|
||||
int fInitializationTimeoutInS; ///< Timeout for the initialization (in seconds)
|
||||
|
||||
@@ -521,7 +524,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
bool fDataCallbacks;
|
||||
std::unordered_map<std::string, InputMsgCallback> fMsgInputs;
|
||||
std::unordered_map<std::string, InputMultipartCallback> fMultipartInputs;
|
||||
std::unordered_map<FairMQ::Transport, std::vector<std::string>> fMultitransportInputs;
|
||||
std::unordered_map<fair::mq::Transport, std::vector<std::string>> fMultitransportInputs;
|
||||
std::unordered_map<std::string, std::pair<uint16_t, uint16_t>> fChannelRegistry;
|
||||
std::vector<std::string> fInputChannelKeys;
|
||||
std::mutex fMultitransportMutex;
|
||||
@@ -532,6 +535,7 @@ class FairMQDevice : public FairMQStateMachine
|
||||
const fair::mq::tools::Version fVersion;
|
||||
float fRate; ///< Rate limiting for ConditionalRun
|
||||
size_t fLastTime; ///< Rate limiting for ConditionalRun
|
||||
std::vector<std::string> fRawCmdLineArgs;
|
||||
};
|
||||
|
||||
#endif /* FAIRMQDEVICE_H_ */
|
||||
|
@@ -28,7 +28,7 @@ class FairMQMessage
|
||||
|
||||
virtual bool SetUsedSize(const size_t size) = 0;
|
||||
|
||||
virtual FairMQ::Transport GetType() const = 0;
|
||||
virtual fair::mq::Transport GetType() const = 0;
|
||||
|
||||
virtual void Copy(const std::unique_ptr<FairMQMessage>& msg) __attribute__((deprecated("Use 'Copy(const FairMQMessage& msg)'"))) = 0;
|
||||
virtual void Copy(const FairMQMessage& msg) = 0;
|
||||
|
@@ -14,14 +14,528 @@
|
||||
|
||||
#include "FairMQStateMachine.h"
|
||||
|
||||
FairMQStateMachine::FairMQStateMachine()
|
||||
// Increase maximum number of boost::msm states (default is 10)
|
||||
// This #define has to be before any msm header includes
|
||||
#define FUSION_MAX_VECTOR_SIZE 20
|
||||
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include <boost/msm/back/tools.hpp>
|
||||
#include <boost/msm/back/metafunctions.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <boost/signals2.hpp> // signal/slot for onStateChange callbacks
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace msmf = boost::msm::front;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
start();
|
||||
namespace mq
|
||||
{
|
||||
namespace fsm
|
||||
{
|
||||
|
||||
// defining events for the boost MSM state machine
|
||||
struct INIT_DEVICE_E { string name() const { return "INIT_DEVICE"; } };
|
||||
struct internal_DEVICE_READY_E { string name() const { return "internal_DEVICE_READY"; } };
|
||||
struct INIT_TASK_E { string name() const { return "INIT_TASK"; } };
|
||||
struct internal_READY_E { string name() const { return "internal_READY"; } };
|
||||
struct RUN_E { string name() const { return "RUN"; } };
|
||||
struct PAUSE_E { string name() const { return "PAUSE"; } };
|
||||
struct STOP_E { string name() const { return "STOP"; } };
|
||||
struct RESET_TASK_E { string name() const { return "RESET_TASK"; } };
|
||||
struct RESET_DEVICE_E { string name() const { return "RESET_DEVICE"; } };
|
||||
struct internal_IDLE_E { string name() const { return "internal_IDLE"; } };
|
||||
struct END_E { string name() const { return "END"; } };
|
||||
struct ERROR_FOUND_E { string name() const { return "ERROR_FOUND"; } };
|
||||
|
||||
// deactivate the warning for non-virtual destructor thrown in the boost library
|
||||
#if defined(__clang__)
|
||||
_Pragma("clang diagnostic push")
|
||||
_Pragma("clang diagnostic ignored \"-Wnon-virtual-dtor\"")
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"")
|
||||
#endif
|
||||
|
||||
// defining the boost MSM state machine
|
||||
struct Machine_ : public msmf::state_machine_def<Machine_>
|
||||
{
|
||||
public:
|
||||
Machine_()
|
||||
: fWork()
|
||||
, fWorkAvailableCondition()
|
||||
, fWorkDoneCondition()
|
||||
, fWorkMutex()
|
||||
, fWorkerTerminated(false)
|
||||
, fWorkActive(false)
|
||||
, fWorkAvailable(false)
|
||||
, fStateChangeSignal()
|
||||
, fStateChangeSignalsMap()
|
||||
, fTerminationRequested(false)
|
||||
, fState()
|
||||
, fWorkerThread()
|
||||
{}
|
||||
|
||||
virtual ~Machine_()
|
||||
{}
|
||||
|
||||
template<typename Event, typename FSM>
|
||||
void on_entry(Event const&, FSM& fsm)
|
||||
{
|
||||
LOG(state) << "Starting FairMQ state machine";
|
||||
fState = FairMQStateMachine::IDLE;
|
||||
fsm.CallStateChangeCallbacks(FairMQStateMachine::IDLE);
|
||||
|
||||
// start a worker thread to execute user states in.
|
||||
fsm.fWorkerThread = thread(&Machine_::Worker, &fsm);
|
||||
}
|
||||
|
||||
template<typename Event, typename FSM>
|
||||
void on_exit(Event const&, FSM& /*fsm*/)
|
||||
{
|
||||
LOG(state) << "Exiting FairMQ state machine";
|
||||
}
|
||||
|
||||
// list of FSM states
|
||||
struct OK_FSM : public msmf::state<> {};
|
||||
struct ERROR_FSM : public msmf::terminate_state<> {};
|
||||
|
||||
struct IDLE_FSM : public msmf::state<> {};
|
||||
struct INITIALIZING_DEVICE_FSM : public msmf::state<> {};
|
||||
struct DEVICE_READY_FSM : public msmf::state<> {};
|
||||
struct INITIALIZING_TASK_FSM : public msmf::state<> {};
|
||||
struct READY_FSM : public msmf::state<> {};
|
||||
struct RUNNING_FSM : public msmf::state<> {};
|
||||
struct PAUSED_FSM : public msmf::state<> {};
|
||||
struct RESETTING_TASK_FSM : public msmf::state<> {};
|
||||
struct RESETTING_DEVICE_FSM : public msmf::state<> {};
|
||||
struct EXITING_FSM : public msmf::state<> {};
|
||||
|
||||
// initial states
|
||||
using initial_state = boost::mpl::vector<IDLE_FSM, OK_FSM>;
|
||||
|
||||
// actions
|
||||
struct IdleFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering IDLE state";
|
||||
fsm.fState = FairMQStateMachine::IDLE;
|
||||
}
|
||||
};
|
||||
|
||||
struct InitDeviceFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::INITIALIZING_DEVICE;
|
||||
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering INITIALIZING DEVICE state";
|
||||
fsm.fWork = fsm.fInitWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceReadyFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering DEVICE READY state";
|
||||
fsm.fState = FairMQStateMachine::DEVICE_READY;
|
||||
}
|
||||
};
|
||||
|
||||
struct InitTaskFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::INITIALIZING_TASK;
|
||||
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering INITIALIZING TASK state";
|
||||
fsm.fWork = fsm.fInitTaskWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ReadyFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering READY state";
|
||||
fsm.fState = FairMQStateMachine::READY;
|
||||
}
|
||||
};
|
||||
|
||||
struct RunFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::RUNNING;
|
||||
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RUNNING state";
|
||||
fsm.fWork = fsm.fRunWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct PauseFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::PAUSED;
|
||||
|
||||
fsm.fUnblockHandler();
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering PAUSED state";
|
||||
fsm.fWork = fsm.fPauseWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ResumeFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::RUNNING;
|
||||
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RUNNING state";
|
||||
fsm.fWork = fsm.fRunWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct StopFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::READY;
|
||||
|
||||
fsm.fUnblockHandler();
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
LOG(state) << "Entering READY state";
|
||||
}
|
||||
};
|
||||
|
||||
struct InternalStopFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::READY;
|
||||
fsm.fUnblockHandler();
|
||||
LOG(state) << "RUNNING state finished without an external event, entering READY state";
|
||||
}
|
||||
};
|
||||
|
||||
struct ResetTaskFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::RESETTING_TASK;
|
||||
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RESETTING TASK state";
|
||||
fsm.fWork = fsm.fResetTaskWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ResetDeviceFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = FairMQStateMachine::RESETTING_DEVICE;
|
||||
|
||||
unique_lock<mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RESETTING DEVICE state";
|
||||
fsm.fWork = fsm.fResetWrapperHandler;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ExitingFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering EXITING state";
|
||||
fsm.fState = FairMQStateMachine::EXITING;
|
||||
fsm.fTerminationRequested = true;
|
||||
fsm.CallStateChangeCallbacks(FairMQStateMachine::EXITING);
|
||||
|
||||
// terminate worker thread
|
||||
{
|
||||
lock_guard<mutex> lock(fsm.fWorkMutex);
|
||||
fsm.fWorkerTerminated = true;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
|
||||
// join the worker thread (executing user states)
|
||||
if (fsm.fWorkerThread.joinable())
|
||||
{
|
||||
fsm.fWorkerThread.join();
|
||||
}
|
||||
|
||||
fsm.fExitHandler();
|
||||
}
|
||||
};
|
||||
|
||||
struct ErrorFoundFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering ERROR state";
|
||||
fsm.fState = FairMQStateMachine::Error;
|
||||
fsm.CallStateChangeCallbacks(FairMQStateMachine::Error);
|
||||
}
|
||||
};
|
||||
|
||||
// Transition table for Machine_
|
||||
struct transition_table : boost::mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
msmf::Row<IDLE_FSM, INIT_DEVICE_E, INITIALIZING_DEVICE_FSM, InitDeviceFct, msmf::none>,
|
||||
msmf::Row<IDLE_FSM, END_E, EXITING_FSM, ExitingFct, msmf::none>,
|
||||
msmf::Row<INITIALIZING_DEVICE_FSM, internal_DEVICE_READY_E, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
|
||||
msmf::Row<DEVICE_READY_FSM, INIT_TASK_E, INITIALIZING_TASK_FSM, InitTaskFct, msmf::none>,
|
||||
msmf::Row<DEVICE_READY_FSM, RESET_DEVICE_E, RESETTING_DEVICE_FSM, ResetDeviceFct, msmf::none>,
|
||||
msmf::Row<INITIALIZING_TASK_FSM, internal_READY_E, READY_FSM, ReadyFct, msmf::none>,
|
||||
msmf::Row<READY_FSM, RUN_E, RUNNING_FSM, RunFct, msmf::none>,
|
||||
msmf::Row<READY_FSM, RESET_TASK_E, RESETTING_TASK_FSM, ResetTaskFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, PAUSE_E, PAUSED_FSM, PauseFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, STOP_E, READY_FSM, StopFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, internal_READY_E, READY_FSM, InternalStopFct, msmf::none>,
|
||||
msmf::Row<PAUSED_FSM, RUN_E, RUNNING_FSM, ResumeFct, msmf::none>,
|
||||
msmf::Row<RESETTING_TASK_FSM, internal_DEVICE_READY_E, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
|
||||
msmf::Row<RESETTING_DEVICE_FSM, internal_IDLE_E, IDLE_FSM, IdleFct, msmf::none>,
|
||||
msmf::Row<OK_FSM, ERROR_FOUND_E, ERROR_FSM, ErrorFoundFct, msmf::none>>
|
||||
{};
|
||||
|
||||
// replaces the default no-transition response.
|
||||
template<typename FSM, typename Event>
|
||||
void no_transition(Event const& e, FSM&, int state)
|
||||
{
|
||||
using recursive_stt = typename boost::msm::back::recursive_get_transition_table<FSM>::type;
|
||||
using all_states = typename boost::msm::back::generate_state_set<recursive_stt>::type;
|
||||
|
||||
string stateName;
|
||||
|
||||
boost::mpl::for_each<all_states, boost::msm::wrap<boost::mpl::placeholders::_1>>(boost::msm::back::get_state_name<recursive_stt>(stateName, state));
|
||||
|
||||
stateName = boost::core::demangle(stateName.c_str());
|
||||
size_t pos = stateName.rfind(":");
|
||||
if (pos != string::npos)
|
||||
{
|
||||
stateName = stateName.substr(pos + 1);
|
||||
stateName = stateName.substr(0, stateName.size() - 4);
|
||||
}
|
||||
|
||||
if (stateName != "OK")
|
||||
{
|
||||
LOG(state) << "No transition from state " << stateName << " on event " << e.name();
|
||||
}
|
||||
}
|
||||
|
||||
static string GetStateName(const int state)
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case FairMQStateMachine::OK:
|
||||
return "OK";
|
||||
case FairMQStateMachine::Error:
|
||||
return "Error";
|
||||
case FairMQStateMachine::IDLE:
|
||||
return "IDLE";
|
||||
case FairMQStateMachine::INITIALIZING_DEVICE:
|
||||
return "INITIALIZING_DEVICE";
|
||||
case FairMQStateMachine::DEVICE_READY:
|
||||
return "DEVICE_READY";
|
||||
case FairMQStateMachine::INITIALIZING_TASK:
|
||||
return "INITIALIZING_TASK";
|
||||
case FairMQStateMachine::READY:
|
||||
return "READY";
|
||||
case FairMQStateMachine::RUNNING:
|
||||
return "RUNNING";
|
||||
case FairMQStateMachine::PAUSED:
|
||||
return "PAUSED";
|
||||
case FairMQStateMachine::RESETTING_TASK:
|
||||
return "RESETTING_TASK";
|
||||
case FairMQStateMachine::RESETTING_DEVICE:
|
||||
return "RESETTING_DEVICE";
|
||||
case FairMQStateMachine::EXITING:
|
||||
return "EXITING";
|
||||
default:
|
||||
return "requested name for non-existent state...";
|
||||
}
|
||||
}
|
||||
|
||||
void CallStateChangeCallbacks(const FairMQStateMachine::State state) const
|
||||
{
|
||||
if (!fStateChangeSignal.empty())
|
||||
{
|
||||
fStateChangeSignal(state);
|
||||
}
|
||||
}
|
||||
|
||||
function<void(void)> fInitWrapperHandler;
|
||||
function<void(void)> fInitTaskWrapperHandler;
|
||||
function<void(void)> fRunWrapperHandler;
|
||||
function<void(void)> fPauseWrapperHandler;
|
||||
function<void(void)> fResetWrapperHandler;
|
||||
function<void(void)> fResetTaskWrapperHandler;
|
||||
function<void(void)> fExitHandler;
|
||||
function<void(void)> fUnblockHandler;
|
||||
|
||||
// function to execute user states in a worker thread
|
||||
function<void(void)> fWork;
|
||||
condition_variable fWorkAvailableCondition;
|
||||
condition_variable fWorkDoneCondition;
|
||||
mutex fWorkMutex;
|
||||
bool fWorkerTerminated;
|
||||
bool fWorkActive;
|
||||
bool fWorkAvailable;
|
||||
|
||||
boost::signals2::signal<void(const FairMQStateMachine::State)> fStateChangeSignal;
|
||||
unordered_map<string, boost::signals2::connection> fStateChangeSignalsMap;
|
||||
atomic<bool> fTerminationRequested;
|
||||
|
||||
atomic<FairMQStateMachine::State> fState;
|
||||
|
||||
private:
|
||||
void Worker()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
unique_lock<mutex> lock(fWorkMutex);
|
||||
// Wait for work to be done.
|
||||
while (!fWorkAvailable && !fWorkerTerminated)
|
||||
{
|
||||
fWorkAvailableCondition.wait(lock);
|
||||
}
|
||||
|
||||
if (fWorkerTerminated)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fWorkActive = true;
|
||||
}
|
||||
|
||||
fWork();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(fWorkMutex);
|
||||
fWorkActive = false;
|
||||
fWorkAvailable = false;
|
||||
fWorkDoneCondition.notify_one();
|
||||
}
|
||||
CallStateChangeCallbacks(fState);
|
||||
}
|
||||
}
|
||||
|
||||
// run state handlers in a separate thread
|
||||
thread fWorkerThread;
|
||||
}; // Machine_
|
||||
|
||||
using FairMQFSM = boost::msm::back::state_machine<Machine_>;
|
||||
|
||||
// reactivate the warning for non-virtual destructor
|
||||
#if defined(__clang__)
|
||||
_Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#endif
|
||||
|
||||
} // namespace fsm
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
|
||||
using namespace fair::mq::fsm;
|
||||
|
||||
FairMQStateMachine::FairMQStateMachine()
|
||||
: fChangeStateMutex()
|
||||
, fFsm(new FairMQFSM)
|
||||
{
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fInitWrapperHandler = bind(&FairMQStateMachine::InitWrapper, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fInitTaskWrapperHandler = bind(&FairMQStateMachine::InitTaskWrapper, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fRunWrapperHandler = bind(&FairMQStateMachine::RunWrapper, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fPauseWrapperHandler = bind(&FairMQStateMachine::PauseWrapper, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fResetWrapperHandler = bind(&FairMQStateMachine::ResetWrapper, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fResetTaskWrapperHandler = bind(&FairMQStateMachine::ResetTaskWrapper, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fExitHandler = bind(&FairMQStateMachine::Exit, this);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fUnblockHandler = bind(&FairMQStateMachine::Unblock, this);
|
||||
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->start();
|
||||
}
|
||||
|
||||
FairMQStateMachine::~FairMQStateMachine()
|
||||
{
|
||||
stop();
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->stop();
|
||||
}
|
||||
|
||||
int FairMQStateMachine::GetInterfaceVersion() const
|
||||
@@ -37,85 +551,85 @@ bool FairMQStateMachine::ChangeState(int event)
|
||||
{
|
||||
case INIT_DEVICE:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::INIT_DEVICE());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(INIT_DEVICE_E());
|
||||
return true;
|
||||
}
|
||||
case internal_DEVICE_READY:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::internal_DEVICE_READY());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_DEVICE_READY_E());
|
||||
return true;
|
||||
}
|
||||
case INIT_TASK:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::INIT_TASK());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(INIT_TASK_E());
|
||||
return true;
|
||||
}
|
||||
case internal_READY:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::internal_READY());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_READY_E());
|
||||
return true;
|
||||
}
|
||||
case RUN:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::RUN());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RUN_E());
|
||||
return true;
|
||||
}
|
||||
case PAUSE:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::PAUSE());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(PAUSE_E());
|
||||
return true;
|
||||
}
|
||||
case STOP:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::STOP());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(STOP_E());
|
||||
return true;
|
||||
}
|
||||
case RESET_DEVICE:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::RESET_DEVICE());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RESET_DEVICE_E());
|
||||
return true;
|
||||
}
|
||||
case RESET_TASK:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::RESET_TASK());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(RESET_TASK_E());
|
||||
return true;
|
||||
}
|
||||
case internal_IDLE:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::internal_IDLE());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(internal_IDLE_E());
|
||||
return true;
|
||||
}
|
||||
case END:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::END());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(END_E());
|
||||
return true;
|
||||
}
|
||||
case ERROR_FOUND:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fChangeStateMutex);
|
||||
process_event(fair::mq::fsm::ERROR_FOUND());
|
||||
lock_guard<mutex> lock(fChangeStateMutex);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->process_event(ERROR_FOUND_E());
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG(error) << "Requested state transition with an unsupported event: " << event << std::endl
|
||||
LOG(error) << "Requested state transition with an unsupported event: " << event << endl
|
||||
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_TASK, RESET_DEVICE, END, ERROR_FOUND";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << "Exception in FairMQStateMachine::ChangeState(): " << e.what();
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -123,7 +637,7 @@ bool FairMQStateMachine::ChangeState(int event)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FairMQStateMachine::ChangeState(const std::string& event)
|
||||
bool FairMQStateMachine::ChangeState(const string& event)
|
||||
{
|
||||
return ChangeState(GetEventNumber(event));
|
||||
}
|
||||
@@ -140,10 +654,10 @@ void FairMQStateMachine::WaitForEndOfState(int event)
|
||||
case RESET_TASK:
|
||||
case RESET_DEVICE:
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fWorkMutex);
|
||||
while (fWorkActive || fWorkAvailable)
|
||||
unique_lock<mutex> lock(static_pointer_cast<FairMQFSM>(fFsm)->fWorkMutex);
|
||||
while (static_pointer_cast<FairMQFSM>(fFsm)->fWorkActive || static_pointer_cast<FairMQFSM>(fFsm)->fWorkAvailable)
|
||||
{
|
||||
fWorkDoneCondition.wait_for(lock, std::chrono::seconds(1));
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fWorkDoneCondition.wait_for(lock, chrono::seconds(1));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -153,13 +667,13 @@ void FairMQStateMachine::WaitForEndOfState(int event)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << "Exception in FairMQStateMachine::WaitForEndOfState(): " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQStateMachine::WaitForEndOfState(const std::string& event)
|
||||
void FairMQStateMachine::WaitForEndOfState(const string& event)
|
||||
{
|
||||
return WaitForEndOfState(GetEventNumber(event));
|
||||
}
|
||||
@@ -176,11 +690,11 @@ bool FairMQStateMachine::WaitForEndOfStateForMs(int event, int durationInMs)
|
||||
case RESET_TASK:
|
||||
case RESET_DEVICE:
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fWorkMutex);
|
||||
while (fWorkActive || fWorkAvailable)
|
||||
unique_lock<mutex> lock(static_pointer_cast<FairMQFSM>(fFsm)->fWorkMutex);
|
||||
while (static_pointer_cast<FairMQFSM>(fFsm)->fWorkActive || static_pointer_cast<FairMQFSM>(fFsm)->fWorkAvailable)
|
||||
{
|
||||
fWorkDoneCondition.wait_for(lock, std::chrono::milliseconds(durationInMs));
|
||||
if (fWorkActive)
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fWorkDoneCondition.wait_for(lock, chrono::milliseconds(durationInMs));
|
||||
if (static_pointer_cast<FairMQFSM>(fFsm)->fWorkActive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -192,32 +706,59 @@ bool FairMQStateMachine::WaitForEndOfStateForMs(int event, int durationInMs)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << "Exception in FairMQStateMachine::WaitForEndOfStateForMs(): " << e.what();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FairMQStateMachine::WaitForEndOfStateForMs(const std::string& event, int durationInMs)
|
||||
bool FairMQStateMachine::WaitForEndOfStateForMs(const string& event, int durationInMs)
|
||||
{
|
||||
return WaitForEndOfStateForMs(GetEventNumber(event), durationInMs);
|
||||
}
|
||||
|
||||
void FairMQStateMachine::SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback)
|
||||
void FairMQStateMachine::SubscribeToStateChange(const string& key, function<void(const State)> callback)
|
||||
{
|
||||
fStateChangeSignalsMap.insert({key, fStateChangeSignal.connect(callback)});
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignalsMap.insert({key, static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignal.connect(callback)});
|
||||
}
|
||||
void FairMQStateMachine::UnsubscribeFromStateChange(const std::string& key)
|
||||
void FairMQStateMachine::UnsubscribeFromStateChange(const string& key)
|
||||
{
|
||||
if (fStateChangeSignalsMap.count(key))
|
||||
if (static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignalsMap.count(key))
|
||||
{
|
||||
fStateChangeSignalsMap.at(key).disconnect();
|
||||
fStateChangeSignalsMap.erase(key);
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignalsMap.at(key).disconnect();
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->fStateChangeSignalsMap.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQStateMachine::GetEventNumber(const std::string& event)
|
||||
void FairMQStateMachine::CallStateChangeCallbacks(const State state) const
|
||||
{
|
||||
static_pointer_cast<FairMQFSM>(fFsm)->CallStateChangeCallbacks(state);
|
||||
}
|
||||
|
||||
string FairMQStateMachine::GetCurrentStateName() const
|
||||
{
|
||||
return static_pointer_cast<FairMQFSM>(fFsm)->GetStateName(static_pointer_cast<FairMQFSM>(fFsm)->fState);
|
||||
}
|
||||
int FairMQStateMachine::GetCurrentState() const
|
||||
{
|
||||
return static_pointer_cast<FairMQFSM>(fFsm)->fState;
|
||||
}
|
||||
bool FairMQStateMachine::CheckCurrentState(int state) const
|
||||
{
|
||||
return state == static_pointer_cast<FairMQFSM>(fFsm)->fState;
|
||||
}
|
||||
bool FairMQStateMachine::CheckCurrentState(string state) const
|
||||
{
|
||||
return state == GetCurrentStateName();
|
||||
}
|
||||
|
||||
bool FairMQStateMachine::Terminated()
|
||||
{
|
||||
return static_pointer_cast<FairMQFSM>(fFsm)->fTerminationRequested;
|
||||
}
|
||||
|
||||
int FairMQStateMachine::GetEventNumber(const string& event)
|
||||
{
|
||||
if (event == "INIT_DEVICE") return INIT_DEVICE;
|
||||
if (event == "INIT_TASK") return INIT_TASK;
|
||||
@@ -228,7 +769,7 @@ int FairMQStateMachine::GetEventNumber(const std::string& event)
|
||||
if (event == "RESET_TASK") return RESET_TASK;
|
||||
if (event == "END") return END;
|
||||
if (event == "ERROR_FOUND") return ERROR_FOUND;
|
||||
LOG(error) << "Requested number for non-existent event... " << event << std::endl
|
||||
LOG(error) << "Requested number for non-existent event... " << event << endl
|
||||
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_DEVICE, RESET_TASK, END, ERROR_FOUND";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -17,555 +17,14 @@
|
||||
|
||||
#define FAIRMQ_INTERFACE_VERSION 3
|
||||
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
// Increase maximum number of boost::msm states (default is 10)
|
||||
// This #define has to be before any msm header includes
|
||||
#define FUSION_MAX_VECTOR_SIZE 20
|
||||
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
#include <boost/msm/back/tools.hpp>
|
||||
#include <boost/msm/back/metafunctions.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
|
||||
#include <boost/signals2.hpp> // signal/slot for onStateChange callbacks
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
namespace msmf = boost::msm::front;
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace fsm
|
||||
{
|
||||
|
||||
// defining events for the boost MSM state machine
|
||||
struct INIT_DEVICE { std::string name() const { return "INIT_DEVICE"; } };
|
||||
struct internal_DEVICE_READY { std::string name() const { return "internal_DEVICE_READY"; } };
|
||||
struct INIT_TASK { std::string name() const { return "INIT_TASK"; } };
|
||||
struct internal_READY { std::string name() const { return "internal_READY"; } };
|
||||
struct RUN { std::string name() const { return "RUN"; } };
|
||||
struct PAUSE { std::string name() const { return "PAUSE"; } };
|
||||
struct STOP { std::string name() const { return "STOP"; } };
|
||||
struct RESET_TASK { std::string name() const { return "RESET_TASK"; } };
|
||||
struct RESET_DEVICE { std::string name() const { return "RESET_DEVICE"; } };
|
||||
struct internal_IDLE { std::string name() const { return "internal_IDLE"; } };
|
||||
struct END { std::string name() const { return "END"; } };
|
||||
struct ERROR_FOUND { std::string name() const { return "ERROR_FOUND"; } };
|
||||
|
||||
// deactivate the warning for non-virtual destructor thrown in the boost library
|
||||
#if defined(__clang__)
|
||||
_Pragma("clang diagnostic push")
|
||||
_Pragma("clang diagnostic ignored \"-Wnon-virtual-dtor\"")
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"")
|
||||
#endif
|
||||
|
||||
// defining the boost MSM state machine
|
||||
struct FairMQFSM : public msmf::state_machine_def<FairMQFSM>
|
||||
{
|
||||
public:
|
||||
FairMQFSM()
|
||||
: fState()
|
||||
, fChangeStateMutex()
|
||||
, fWork()
|
||||
, fWorkAvailableCondition()
|
||||
, fWorkDoneCondition()
|
||||
, fWorkMutex()
|
||||
, fWorkerTerminated(false)
|
||||
, fWorkActive(false)
|
||||
, fWorkAvailable(false)
|
||||
, fStateChangeSignal()
|
||||
, fStateChangeSignalsMap()
|
||||
, fTerminationRequested(false)
|
||||
, fWorkerThread()
|
||||
{}
|
||||
|
||||
virtual ~FairMQFSM()
|
||||
{}
|
||||
|
||||
template<typename Event, typename FSM>
|
||||
void on_entry(Event const&, FSM& fsm)
|
||||
{
|
||||
LOG(state) << "Starting FairMQ state machine";
|
||||
fState = IDLE;
|
||||
fsm.CallStateChangeCallbacks(IDLE);
|
||||
|
||||
// start a worker thread to execute user states in.
|
||||
fsm.fWorkerThread = std::thread(&FairMQFSM::Worker, &fsm);
|
||||
}
|
||||
|
||||
template<typename Event, typename FSM>
|
||||
void on_exit(Event const&, FSM& /*fsm*/)
|
||||
{
|
||||
LOG(state) << "Exiting FairMQ state machine";
|
||||
}
|
||||
|
||||
// list of FSM states
|
||||
struct OK_FSM : public msmf::state<> {};
|
||||
struct ERROR_FSM : public msmf::terminate_state<> {};
|
||||
|
||||
struct IDLE_FSM : public msmf::state<> {};
|
||||
struct INITIALIZING_DEVICE_FSM : public msmf::state<> {};
|
||||
struct DEVICE_READY_FSM : public msmf::state<> {};
|
||||
struct INITIALIZING_TASK_FSM : public msmf::state<> {};
|
||||
struct READY_FSM : public msmf::state<> {};
|
||||
struct RUNNING_FSM : public msmf::state<> {};
|
||||
struct PAUSED_FSM : public msmf::state<> {};
|
||||
struct RESETTING_TASK_FSM : public msmf::state<> {};
|
||||
struct RESETTING_DEVICE_FSM : public msmf::state<> {};
|
||||
struct EXITING_FSM : public msmf::state<> {};
|
||||
|
||||
// initial states
|
||||
using initial_state = boost::mpl::vector<IDLE_FSM, OK_FSM>;
|
||||
|
||||
// actions
|
||||
struct IdleFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering IDLE state";
|
||||
fsm.fState = IDLE;
|
||||
}
|
||||
};
|
||||
|
||||
struct InitDeviceFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = INITIALIZING_DEVICE;
|
||||
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering INITIALIZING DEVICE state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::InitWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceReadyFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering DEVICE READY state";
|
||||
fsm.fState = DEVICE_READY;
|
||||
}
|
||||
};
|
||||
|
||||
struct InitTaskFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = INITIALIZING_TASK;
|
||||
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering INITIALIZING TASK state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::InitTaskWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ReadyFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering READY state";
|
||||
fsm.fState = READY;
|
||||
}
|
||||
};
|
||||
|
||||
struct RunFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = RUNNING;
|
||||
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RUNNING state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::RunWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct PauseFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = PAUSED;
|
||||
|
||||
fsm.Unblock();
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering PAUSED state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::PauseWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ResumeFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = RUNNING;
|
||||
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RUNNING state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::RunWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct StopFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = READY;
|
||||
|
||||
fsm.Unblock();
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
LOG(state) << "Entering READY state";
|
||||
}
|
||||
};
|
||||
|
||||
struct InternalStopFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = READY;
|
||||
fsm.Unblock();
|
||||
LOG(state) << "RUNNING state finished without an external event, entering READY state";
|
||||
}
|
||||
};
|
||||
|
||||
struct ResetTaskFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = RESETTING_TASK;
|
||||
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RESETTING TASK state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::ResetTaskWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ResetDeviceFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
fsm.fState = RESETTING_DEVICE;
|
||||
|
||||
std::unique_lock<std::mutex> lock(fsm.fWorkMutex);
|
||||
while (fsm.fWorkActive)
|
||||
{
|
||||
fsm.fWorkDoneCondition.wait(lock);
|
||||
}
|
||||
fsm.fWorkAvailable = true;
|
||||
LOG(state) << "Entering RESETTING DEVICE state";
|
||||
fsm.fWork = std::bind(&FairMQFSM::ResetWrapper, &fsm);
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
struct ExitingFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering EXITING state";
|
||||
fsm.fState = EXITING;
|
||||
fsm.fTerminationRequested = true;
|
||||
fsm.CallStateChangeCallbacks(EXITING);
|
||||
|
||||
// terminate worker thread
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fsm.fWorkMutex);
|
||||
fsm.fWorkerTerminated = true;
|
||||
fsm.fWorkAvailableCondition.notify_one();
|
||||
}
|
||||
|
||||
// join the worker thread (executing user states)
|
||||
if (fsm.fWorkerThread.joinable())
|
||||
{
|
||||
fsm.fWorkerThread.join();
|
||||
}
|
||||
|
||||
fsm.Exit();
|
||||
}
|
||||
};
|
||||
|
||||
struct ErrorFoundFct
|
||||
{
|
||||
template<typename EVT, typename FSM, typename SourceState, typename TargetState>
|
||||
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
LOG(state) << "Entering ERROR state";
|
||||
fsm.fState = Error;
|
||||
fsm.CallStateChangeCallbacks(Error);
|
||||
}
|
||||
};
|
||||
|
||||
// Transition table for FairMQFSM
|
||||
struct transition_table : boost::mpl::vector<
|
||||
// Start Event Next Action Guard
|
||||
msmf::Row<IDLE_FSM, INIT_DEVICE, INITIALIZING_DEVICE_FSM, InitDeviceFct, msmf::none>,
|
||||
msmf::Row<IDLE_FSM, END, EXITING_FSM, ExitingFct, msmf::none>,
|
||||
msmf::Row<INITIALIZING_DEVICE_FSM, internal_DEVICE_READY, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
|
||||
msmf::Row<DEVICE_READY_FSM, INIT_TASK, INITIALIZING_TASK_FSM, InitTaskFct, msmf::none>,
|
||||
msmf::Row<DEVICE_READY_FSM, RESET_DEVICE, RESETTING_DEVICE_FSM, ResetDeviceFct, msmf::none>,
|
||||
msmf::Row<INITIALIZING_TASK_FSM, internal_READY, READY_FSM, ReadyFct, msmf::none>,
|
||||
msmf::Row<READY_FSM, RUN, RUNNING_FSM, RunFct, msmf::none>,
|
||||
msmf::Row<READY_FSM, RESET_TASK, RESETTING_TASK_FSM, ResetTaskFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, PAUSE, PAUSED_FSM, PauseFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, STOP, READY_FSM, StopFct, msmf::none>,
|
||||
msmf::Row<RUNNING_FSM, internal_READY, READY_FSM, InternalStopFct, msmf::none>,
|
||||
msmf::Row<PAUSED_FSM, RUN, RUNNING_FSM, ResumeFct, msmf::none>,
|
||||
msmf::Row<RESETTING_TASK_FSM, internal_DEVICE_READY, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
|
||||
msmf::Row<RESETTING_DEVICE_FSM, internal_IDLE, IDLE_FSM, IdleFct, msmf::none>,
|
||||
msmf::Row<OK_FSM, ERROR_FOUND, ERROR_FSM, ErrorFoundFct, msmf::none>>
|
||||
{};
|
||||
|
||||
// replaces the default no-transition response.
|
||||
template<typename FSM, typename Event>
|
||||
void no_transition(Event const& e, FSM&, int state)
|
||||
{
|
||||
using recursive_stt = typename boost::msm::back::recursive_get_transition_table<FSM>::type;
|
||||
using all_states = typename boost::msm::back::generate_state_set<recursive_stt>::type;
|
||||
|
||||
std::string stateName;
|
||||
|
||||
boost::mpl::for_each<all_states, boost::msm::wrap<boost::mpl::placeholders::_1>>(boost::msm::back::get_state_name<recursive_stt>(stateName, state));
|
||||
|
||||
stateName = stateName.substr(24);
|
||||
std::size_t pos = stateName.find("_FSME");
|
||||
stateName.erase(pos);
|
||||
|
||||
if (stateName == "1RUNNING" || stateName == "6DEVICE_READY" || stateName == "0PAUSED" || stateName == "8RESETTING_TASK" || stateName == "0RESETTING_DEVICE")
|
||||
{
|
||||
stateName = stateName.substr(1);
|
||||
}
|
||||
|
||||
if (stateName != "OK")
|
||||
{
|
||||
LOG(state) << "No transition from state " << stateName << " on event " << e.name();
|
||||
}
|
||||
|
||||
// LOG(state) << "no transition from state " << GetStateName(state) << " (" << state << ") on event " << e.name();
|
||||
}
|
||||
|
||||
// backward compatibility to FairMQStateMachine
|
||||
enum State
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
IDLE,
|
||||
INITIALIZING_DEVICE,
|
||||
DEVICE_READY,
|
||||
INITIALIZING_TASK,
|
||||
READY,
|
||||
RUNNING,
|
||||
PAUSED,
|
||||
RESETTING_TASK,
|
||||
RESETTING_DEVICE,
|
||||
EXITING
|
||||
};
|
||||
|
||||
static std::string GetStateName(const int state)
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case OK:
|
||||
return "OK";
|
||||
case Error:
|
||||
return "Error";
|
||||
case IDLE:
|
||||
return "IDLE";
|
||||
case INITIALIZING_DEVICE:
|
||||
return "INITIALIZING_DEVICE";
|
||||
case DEVICE_READY:
|
||||
return "DEVICE_READY";
|
||||
case INITIALIZING_TASK:
|
||||
return "INITIALIZING_TASK";
|
||||
case READY:
|
||||
return "READY";
|
||||
case RUNNING:
|
||||
return "RUNNING";
|
||||
case PAUSED:
|
||||
return "PAUSED";
|
||||
case RESETTING_TASK:
|
||||
return "RESETTING_TASK";
|
||||
case RESETTING_DEVICE:
|
||||
return "RESETTING_DEVICE";
|
||||
case EXITING:
|
||||
return "EXITING";
|
||||
default:
|
||||
return "requested name for non-existent state...";
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetCurrentStateName() const
|
||||
{
|
||||
return GetStateName(fState);
|
||||
}
|
||||
int GetCurrentState() const
|
||||
{
|
||||
return fState;
|
||||
}
|
||||
bool CheckCurrentState(int state) const
|
||||
{
|
||||
return state == fState;
|
||||
}
|
||||
bool CheckCurrentState(std::string state) const
|
||||
{
|
||||
return state == GetCurrentStateName();
|
||||
}
|
||||
|
||||
// actions to be overwritten by derived classes
|
||||
virtual void InitWrapper() {}
|
||||
virtual void InitTaskWrapper() {}
|
||||
virtual void RunWrapper() {}
|
||||
virtual void PauseWrapper() {}
|
||||
virtual void ResetWrapper() {}
|
||||
virtual void ResetTaskWrapper() {}
|
||||
virtual void Exit() {}
|
||||
virtual void Unblock() {}
|
||||
|
||||
bool Terminated()
|
||||
{
|
||||
return fTerminationRequested;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::atomic<State> fState;
|
||||
std::mutex fChangeStateMutex;
|
||||
|
||||
// function to execute user states in a worker thread
|
||||
std::function<void(void)> fWork;
|
||||
std::condition_variable fWorkAvailableCondition;
|
||||
std::condition_variable fWorkDoneCondition;
|
||||
std::mutex fWorkMutex;
|
||||
bool fWorkerTerminated;
|
||||
bool fWorkActive;
|
||||
bool fWorkAvailable;
|
||||
|
||||
boost::signals2::signal<void(const State)> fStateChangeSignal;
|
||||
std::unordered_map<std::string, boost::signals2::connection> fStateChangeSignalsMap;
|
||||
std::atomic<bool> fTerminationRequested;
|
||||
|
||||
void CallStateChangeCallbacks(const State state) const
|
||||
{
|
||||
if (!fStateChangeSignal.empty())
|
||||
{
|
||||
fStateChangeSignal(state);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Worker()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fWorkMutex);
|
||||
// Wait for work to be done.
|
||||
while (!fWorkAvailable && !fWorkerTerminated)
|
||||
{
|
||||
fWorkAvailableCondition.wait(lock);
|
||||
}
|
||||
|
||||
if (fWorkerTerminated)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fWorkActive = true;
|
||||
}
|
||||
|
||||
fWork();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(fWorkMutex);
|
||||
fWorkActive = false;
|
||||
fWorkAvailable = false;
|
||||
fWorkDoneCondition.notify_one();
|
||||
}
|
||||
CallStateChangeCallbacks(fState);
|
||||
}
|
||||
}
|
||||
|
||||
// run state handlers in a separate thread
|
||||
std::thread fWorkerThread;
|
||||
};
|
||||
|
||||
// reactivate the warning for non-virtual destructor
|
||||
#if defined(__clang__)
|
||||
_Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#endif
|
||||
|
||||
} // namespace fsm
|
||||
} // namespace mq
|
||||
} // namespace fair
|
||||
|
||||
class FairMQStateMachine : public boost::msm::back::state_machine<fair::mq::fsm::FairMQFSM>
|
||||
class FairMQStateMachine
|
||||
{
|
||||
public:
|
||||
enum Event
|
||||
@@ -584,6 +43,22 @@ class FairMQStateMachine : public boost::msm::back::state_machine<fair::mq::fsm:
|
||||
ERROR_FOUND
|
||||
};
|
||||
|
||||
enum State
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
IDLE,
|
||||
INITIALIZING_DEVICE,
|
||||
DEVICE_READY,
|
||||
INITIALIZING_TASK,
|
||||
READY,
|
||||
RUNNING,
|
||||
PAUSED,
|
||||
RESETTING_TASK,
|
||||
RESETTING_DEVICE,
|
||||
EXITING
|
||||
};
|
||||
|
||||
FairMQStateMachine();
|
||||
virtual ~FairMQStateMachine();
|
||||
|
||||
@@ -601,8 +76,30 @@ class FairMQStateMachine : public boost::msm::back::state_machine<fair::mq::fsm:
|
||||
void SubscribeToStateChange(const std::string& key, std::function<void(const State)> callback);
|
||||
void UnsubscribeFromStateChange(const std::string& key);
|
||||
|
||||
void CallStateChangeCallbacks(const State state) const;
|
||||
|
||||
std::string GetCurrentStateName() const;
|
||||
int GetCurrentState() const;
|
||||
bool CheckCurrentState(int state) const;
|
||||
bool CheckCurrentState(std::string state) const;
|
||||
bool Terminated();
|
||||
|
||||
// actions to be overwritten by derived classes
|
||||
virtual void InitWrapper() {}
|
||||
virtual void InitTaskWrapper() {}
|
||||
virtual void RunWrapper() {}
|
||||
virtual void PauseWrapper() {}
|
||||
virtual void ResetWrapper() {}
|
||||
virtual void ResetTaskWrapper() {}
|
||||
virtual void Exit() {}
|
||||
virtual void Unblock() {}
|
||||
|
||||
private:
|
||||
int GetEventNumber(const std::string& event);
|
||||
|
||||
std::mutex fChangeStateMutex;
|
||||
|
||||
std::shared_ptr<void> fFsm;
|
||||
};
|
||||
|
||||
#endif /* FAIRMQSTATEMACHINE_H_ */
|
||||
|
@@ -29,7 +29,7 @@ class FairMQTransportFactory
|
||||
private:
|
||||
/// Topology wide unique id
|
||||
const std::string fkId;
|
||||
|
||||
|
||||
public:
|
||||
/// ctor
|
||||
/// @param id Topology wide unique id, usually the device id.
|
||||
@@ -69,7 +69,7 @@ class FairMQTransportFactory
|
||||
virtual FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr) const = 0;
|
||||
|
||||
/// Get transport type
|
||||
virtual FairMQ::Transport GetType() const = 0;
|
||||
virtual fair::mq::Transport GetType() const = 0;
|
||||
|
||||
virtual void Interrupt() = 0;
|
||||
virtual void Resume() = 0;
|
||||
|
@@ -99,6 +99,11 @@ class Plugin
|
||||
auto SubscribeToPropertyChangeAsString(std::function<void(const std::string& key, std::string newValue)> callback) -> void { fPluginServices->SubscribeToPropertyChangeAsString(fkName, callback); }
|
||||
auto UnsubscribeFromPropertyChangeAsString() -> void { fPluginServices->UnsubscribeFromPropertyChangeAsString(fkName); }
|
||||
|
||||
auto CycleLogConsoleSeverityUp() -> void { fPluginServices->CycleLogConsoleSeverityUp(); }
|
||||
auto CycleLogConsoleSeverityDown() -> void { fPluginServices->CycleLogConsoleSeverityDown(); }
|
||||
auto CycleLogVerbosityUp() -> void { fPluginServices->CycleLogVerbosityUp(); }
|
||||
auto CycleLogVerbosityDown() -> void { fPluginServices->CycleLogVerbosityDown(); }
|
||||
|
||||
private:
|
||||
const std::string fkName;
|
||||
const Version fkVersion;
|
||||
|
@@ -6,6 +6,7 @@
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <fairmq/plugins/Builtin.h>
|
||||
#include <fairmq/PluginManager.h>
|
||||
#include <fairmq/Tools.h>
|
||||
#include <boost/program_options.hpp>
|
||||
|
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <fairmq/Plugin.h>
|
||||
#include <fairmq/PluginServices.h>
|
||||
#include <fairmq/plugins/Builtin.h>
|
||||
#include <fairmq/Tools.h>
|
||||
#include <FairMQDevice.h>
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
|
@@ -253,6 +253,10 @@ class PluginServices
|
||||
/// @param subscriber
|
||||
auto UnsubscribeFromPropertyChangeAsString(const std::string& subscriber) -> void { fConfig->UnsubscribeAsString(subscriber); }
|
||||
|
||||
auto CycleLogConsoleSeverityUp() -> void { Logger::CycleConsoleSeverityUp(); }
|
||||
auto CycleLogConsoleSeverityDown() -> void { Logger::CycleConsoleSeverityDown(); }
|
||||
auto CycleLogVerbosityUp() -> void { Logger::CycleVerbosityUp(); }
|
||||
auto CycleLogVerbosityDown() -> void { Logger::CycleVerbosityDown(); }
|
||||
|
||||
static const std::unordered_map<std::string, DeviceState> fkDeviceStateStrMap;
|
||||
static const std::unordered_map<DeviceState, std::string, tools::HashEnum<DeviceState>> fkStrDeviceStateMap;
|
||||
|
@@ -15,8 +15,9 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
/// TODO deprecate this namespace
|
||||
namespace FairMQ
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
|
||||
enum class Transport
|
||||
@@ -28,6 +29,21 @@ enum class Transport
|
||||
OFI
|
||||
};
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<>
|
||||
struct hash<fair::mq::Transport> : fair::mq::tools::HashEnum<fair::mq::Transport> {};
|
||||
|
||||
} /* namespace std */
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
|
||||
static std::unordered_map<std::string, Transport> TransportTypes {
|
||||
{ "default", Transport::DEFAULT },
|
||||
@@ -37,25 +53,15 @@ static std::unordered_map<std::string, Transport> TransportTypes {
|
||||
{ "ofi", Transport::OFI }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
|
||||
using Transport = ::FairMQ::Transport;
|
||||
using ::FairMQ::TransportTypes;
|
||||
static std::unordered_map<Transport, std::string> TransportNames {
|
||||
{ Transport::DEFAULT, "default" },
|
||||
{ Transport::ZMQ, "zeromq" },
|
||||
{ Transport::NN, "nanomsg" },
|
||||
{ Transport::SHM, "shmem" },
|
||||
{ Transport::OFI, "ofi" }
|
||||
};
|
||||
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<>
|
||||
struct hash<FairMQ::Transport> : fair::mq::tools::HashEnum<FairMQ::Transport> {};
|
||||
|
||||
} /* namespace std */
|
||||
|
||||
#endif /* FAIR_MQ_TRANSPORTS_H */
|
||||
|
@@ -57,7 +57,7 @@ void FairMQBenchmarkSampler::Run()
|
||||
// store the channel reference to avoid traversing the map on every loop iteration
|
||||
FairMQChannel& dataOutChannel = fChannels.at(fOutChannelName).at(0);
|
||||
|
||||
FairMQMessagePtr baseMsg(dataOutChannel.Transport()->CreateMessage(fMsgSize));
|
||||
FairMQMessagePtr baseMsg(dataOutChannel.NewMessage(fMsgSize));
|
||||
|
||||
LOG(info) << "Starting the benchmark with message size of " << fMsgSize << " and " << fMaxIterations << " iterations.";
|
||||
auto tStart = chrono::high_resolution_clock::now();
|
||||
@@ -66,7 +66,7 @@ void FairMQBenchmarkSampler::Run()
|
||||
{
|
||||
if (fSameMessage)
|
||||
{
|
||||
FairMQMessagePtr msg(dataOutChannel.Transport()->CreateMessage());
|
||||
FairMQMessagePtr msg(dataOutChannel.NewMessage());
|
||||
msg->Copy(*baseMsg);
|
||||
|
||||
if (dataOutChannel.Send(msg) >= 0)
|
||||
@@ -83,7 +83,7 @@ void FairMQBenchmarkSampler::Run()
|
||||
}
|
||||
else
|
||||
{
|
||||
FairMQMessagePtr msg(dataOutChannel.Transport()->CreateMessage(fMsgSize));
|
||||
FairMQMessagePtr msg(dataOutChannel.NewMessage(fMsgSize));
|
||||
|
||||
if (dataOutChannel.Send(msg) >= 0)
|
||||
{
|
||||
|
@@ -1,69 +0,0 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/**
|
||||
* FairMQSink.cxx
|
||||
*
|
||||
* @since 2013-01-09
|
||||
* @author D. Klein, A. Rybalchenko
|
||||
*/
|
||||
|
||||
#include "FairMQSink.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "../FairMQLogger.h"
|
||||
#include "../options/FairMQProgOptions.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQSink::FairMQSink()
|
||||
: fNumMsgs(0)
|
||||
, fInChannelName()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQSink::InitTask()
|
||||
{
|
||||
fNumMsgs = fConfig->GetValue<uint64_t>("num-msgs");
|
||||
fInChannelName = fConfig->GetValue<string>("in-channel");
|
||||
}
|
||||
|
||||
void FairMQSink::Run()
|
||||
{
|
||||
uint64_t numReceivedMsgs = 0;
|
||||
// store the channel reference to avoid traversing the map on every loop iteration
|
||||
FairMQChannel& dataInChannel = fChannels.at(fInChannelName).at(0);
|
||||
|
||||
LOG(info) << "Starting the benchmark and expecting to receive " << fNumMsgs << " messages.";
|
||||
auto tStart = chrono::high_resolution_clock::now();
|
||||
|
||||
while (CheckCurrentState(RUNNING))
|
||||
{
|
||||
FairMQMessagePtr msg(dataInChannel.Transport()->CreateMessage());
|
||||
|
||||
if (dataInChannel.Receive(msg) >= 0)
|
||||
{
|
||||
if (fNumMsgs > 0)
|
||||
{
|
||||
if (numReceivedMsgs >= fNumMsgs)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
numReceivedMsgs++;
|
||||
}
|
||||
}
|
||||
|
||||
auto tEnd = chrono::high_resolution_clock::now();
|
||||
|
||||
LOG(info) << "Leaving RUNNING state. Received " << numReceivedMsgs << " messages in " << chrono::duration<double, milli>(tEnd - tStart).count() << "ms.";
|
||||
}
|
||||
|
||||
FairMQSink::~FairMQSink()
|
||||
{
|
||||
}
|
@@ -56,7 +56,7 @@ class FairMQSink : public FairMQDevice//, public OutputPolicy
|
||||
|
||||
while (CheckCurrentState(RUNNING))
|
||||
{
|
||||
FairMQMessagePtr msg(dataInChannel.Transport()->CreateMessage());
|
||||
FairMQMessagePtr msg(dataInChannel.NewMessage());
|
||||
|
||||
if (dataInChannel.Receive(msg) >= 0)
|
||||
{
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQ::Transport FairMQMessageNN::fTransportType = FairMQ::Transport::NN;
|
||||
fair::mq::Transport FairMQMessageNN::fTransportType = fair::mq::Transport::NN;
|
||||
|
||||
FairMQMessageNN::FairMQMessageNN()
|
||||
: fMessage(nullptr)
|
||||
@@ -172,7 +172,7 @@ void FairMQMessageNN::SetMessage(void* data, const size_t size)
|
||||
fSize = size;
|
||||
}
|
||||
|
||||
FairMQ::Transport FairMQMessageNN::GetType() const
|
||||
fair::mq::Transport FairMQMessageNN::GetType() const
|
||||
{
|
||||
return fTransportType;
|
||||
}
|
||||
|
@@ -46,7 +46,7 @@ class FairMQMessageNN : public FairMQMessage
|
||||
|
||||
bool SetUsedSize(const size_t size) override;
|
||||
|
||||
FairMQ::Transport GetType() const override;
|
||||
fair::mq::Transport GetType() const override;
|
||||
|
||||
void Copy(const FairMQMessage& msg) override;
|
||||
void Copy(const FairMQMessagePtr& msg) override;
|
||||
@@ -59,7 +59,7 @@ class FairMQMessageNN : public FairMQMessage
|
||||
size_t fHint;
|
||||
bool fReceiving;
|
||||
FairMQUnmanagedRegion* fRegionPtr;
|
||||
static FairMQ::Transport fTransportType;
|
||||
static fair::mq::Transport fTransportType;
|
||||
|
||||
void* GetMessage() const;
|
||||
void CloseMessage();
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQ::Transport FairMQTransportFactoryNN::fTransportType = FairMQ::Transport::NN;
|
||||
fair::mq::Transport FairMQTransportFactoryNN::fTransportType = fair::mq::Transport::NN;
|
||||
|
||||
FairMQTransportFactoryNN::FairMQTransportFactoryNN(const string& id, const FairMQProgOptions* /*config*/)
|
||||
: FairMQTransportFactory(id)
|
||||
@@ -70,7 +70,7 @@ FairMQUnmanagedRegionPtr FairMQTransportFactoryNN::CreateUnmanagedRegion(const s
|
||||
return unique_ptr<FairMQUnmanagedRegion>(new FairMQUnmanagedRegionNN(size, callback));
|
||||
}
|
||||
|
||||
FairMQ::Transport FairMQTransportFactoryNN::GetType() const
|
||||
fair::mq::Transport FairMQTransportFactoryNN::GetType() const
|
||||
{
|
||||
return fTransportType;
|
||||
}
|
||||
|
@@ -39,13 +39,13 @@ class FairMQTransportFactoryNN : public FairMQTransportFactory
|
||||
|
||||
FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback) const override;
|
||||
|
||||
FairMQ::Transport GetType() const override;
|
||||
fair::mq::Transport GetType() const override;
|
||||
|
||||
void Interrupt() override { FairMQSocketNN::Interrupt(); }
|
||||
void Resume() override { FairMQSocketNN::Resume(); }
|
||||
|
||||
private:
|
||||
static FairMQ::Transport fTransportType;
|
||||
static fair::mq::Transport fTransportType;
|
||||
};
|
||||
|
||||
#endif /* FAIRMQTRANSPORTFACTORYNN_H_ */
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -26,11 +27,16 @@ namespace parser
|
||||
{
|
||||
|
||||
// TODO : add key-value map<string,string> parameter for replacing/updating values from keys
|
||||
// function that convert property tree (given the json structure) to FairMQMap
|
||||
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& id, const string& rootNode)
|
||||
// function that convert property tree (given the json structure) to FairMQChannelMap
|
||||
FairMQChannelMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& id, const string& rootNode)
|
||||
{
|
||||
if (id == "")
|
||||
{
|
||||
throw ParserError("no device ID provided. Provide with `--id` cmd option");
|
||||
}
|
||||
|
||||
// Create fair mq map
|
||||
FairMQMap channelMap;
|
||||
FairMQChannelMap channelMap;
|
||||
// boost::property_tree::json_parser::write_json(std::cout, pt);
|
||||
// Helper::PrintDeviceList(pt.get_child(rootNode));
|
||||
// Extract value from boost::property_tree
|
||||
@@ -45,20 +51,13 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& id,
|
||||
return channelMap;
|
||||
}
|
||||
|
||||
FairMQMap JSON::UserParser(const string& filename, const string& deviceId, const string& rootNode)
|
||||
FairMQChannelMap JSON::UserParser(const string& filename, const string& deviceId, const string& rootNode)
|
||||
{
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_json(filename, pt);
|
||||
return ptreeToMQMap(pt, deviceId, rootNode);
|
||||
}
|
||||
|
||||
FairMQMap JSON::UserParser(stringstream& input, const string& deviceId, const string& rootNode)
|
||||
{
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_json(input, pt);
|
||||
return ptreeToMQMap(pt, deviceId, rootNode);
|
||||
}
|
||||
|
||||
namespace Helper
|
||||
{
|
||||
|
||||
@@ -89,7 +88,7 @@ void PrintDeviceList(const boost::property_tree::ptree& tree)
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const string& deviceId)
|
||||
void DeviceParser(const boost::property_tree::ptree& tree, FairMQChannelMap& channelMap, const string& deviceId)
|
||||
{
|
||||
string deviceIdKey;
|
||||
|
||||
@@ -128,7 +127,7 @@ void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap)
|
||||
void ChannelParser(const boost::property_tree::ptree& tree, FairMQChannelMap& channelMap)
|
||||
{
|
||||
string channelKey;
|
||||
|
||||
@@ -147,7 +146,7 @@ void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMa
|
||||
commonChannel.UpdateType(q.second.get<string>("type", commonChannel.GetType()));
|
||||
commonChannel.UpdateMethod(q.second.get<string>("method", commonChannel.GetMethod()));
|
||||
commonChannel.UpdateAddress(q.second.get<string>("address", commonChannel.GetAddress()));
|
||||
commonChannel.UpdateTransport(q.second.get<string>("transport", commonChannel.GetTransport()));
|
||||
commonChannel.UpdateTransport(q.second.get<string>("transport", commonChannel.GetTransportName()));
|
||||
commonChannel.UpdateSndBufSize(q.second.get<int>("sndBufSize", commonChannel.GetSndBufSize()));
|
||||
commonChannel.UpdateRcvBufSize(q.second.get<int>("rcvBufSize", commonChannel.GetRcvBufSize()));
|
||||
commonChannel.UpdateSndKernelSize(q.second.get<int>("sndKernelSize", commonChannel.GetSndKernelSize()));
|
||||
@@ -166,7 +165,7 @@ void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMa
|
||||
LOG(debug) << "\ttype = " << commonChannel.GetType();
|
||||
LOG(debug) << "\tmethod = " << commonChannel.GetMethod();
|
||||
LOG(debug) << "\taddress = " << commonChannel.GetAddress();
|
||||
LOG(debug) << "\ttransport = " << commonChannel.GetTransport();
|
||||
LOG(debug) << "\ttransport = " << commonChannel.GetTransportName();
|
||||
LOG(debug) << "\tsndBufSize = " << commonChannel.GetSndBufSize();
|
||||
LOG(debug) << "\trcvBufSize = " << commonChannel.GetRcvBufSize();
|
||||
LOG(debug) << "\tsndKernelSize = " << commonChannel.GetSndKernelSize();
|
||||
@@ -208,7 +207,7 @@ void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>
|
||||
channel.UpdateType(q.second.get<string>("type", channel.GetType()));
|
||||
channel.UpdateMethod(q.second.get<string>("method", channel.GetMethod()));
|
||||
channel.UpdateAddress(q.second.get<string>("address", channel.GetAddress()));
|
||||
channel.UpdateTransport(q.second.get<string>("transport", channel.GetTransport()));
|
||||
channel.UpdateTransport(q.second.get<string>("transport", channel.GetTransportName()));
|
||||
channel.UpdateSndBufSize(q.second.get<int>("sndBufSize", channel.GetSndBufSize()));
|
||||
channel.UpdateRcvBufSize(q.second.get<int>("rcvBufSize", channel.GetRcvBufSize()));
|
||||
channel.UpdateSndKernelSize(q.second.get<int>("sndKernelSize", channel.GetSndKernelSize()));
|
||||
@@ -219,7 +218,7 @@ void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>
|
||||
LOG(debug) << "\ttype = " << channel.GetType();
|
||||
LOG(debug) << "\tmethod = " << channel.GetMethod();
|
||||
LOG(debug) << "\taddress = " << channel.GetAddress();
|
||||
LOG(debug) << "\ttransport = " << channel.GetTransport();
|
||||
LOG(debug) << "\ttransport = " << channel.GetTransportName();
|
||||
LOG(debug) << "\tsndBufSize = " << channel.GetSndBufSize();
|
||||
LOG(debug) << "\trcvBufSize = " << channel.GetRcvBufSize();
|
||||
LOG(debug) << "\tsndKernelSize = " << channel.GetSndKernelSize();
|
||||
@@ -247,7 +246,7 @@ void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>
|
||||
LOG(debug) << "\ttype = " << channel.GetType();
|
||||
LOG(debug) << "\tmethod = " << channel.GetMethod();
|
||||
LOG(debug) << "\taddress = " << channel.GetAddress();
|
||||
LOG(debug) << "\ttransport = " << channel.GetTransport();
|
||||
LOG(debug) << "\ttransport = " << channel.GetTransportName();
|
||||
LOG(debug) << "\tsndBufSize = " << channel.GetSndBufSize();
|
||||
LOG(debug) << "\trcvBufSize = " << channel.GetRcvBufSize();
|
||||
LOG(debug) << "\tsndKernelSize = " << channel.GetSndKernelSize();
|
||||
|
@@ -10,10 +10,10 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <exception>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
#include "FairMQChannel.h"
|
||||
|
||||
@@ -24,22 +24,23 @@ namespace mq
|
||||
namespace parser
|
||||
{
|
||||
|
||||
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
|
||||
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode);
|
||||
struct ParserError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
FairMQChannelMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode);
|
||||
|
||||
struct JSON
|
||||
{
|
||||
FairMQMap UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||
FairMQChannelMap UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||
};
|
||||
|
||||
namespace Helper
|
||||
{
|
||||
|
||||
void PrintDeviceList(const boost::property_tree::ptree& tree);
|
||||
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId);
|
||||
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap);
|
||||
void DeviceParser(const boost::property_tree::ptree& tree, FairMQChannelMap& channelMap, const std::string& deviceId);
|
||||
void ChannelParser(const boost::property_tree::ptree& tree, FairMQChannelMap& channelMap);
|
||||
void SocketParser(const boost::property_tree::ptree& tree, std::vector<FairMQChannel>& channelList, const std::string& channelName, const FairMQChannel& commonChannel);
|
||||
|
||||
} // Helper namespace
|
||||
|
@@ -12,25 +12,70 @@
|
||||
* Created on March 11, 2015, 10:20 PM
|
||||
*/
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
#include "FairProgOptionsHelper.h"
|
||||
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQSuboptParser.h"
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp> // join/split
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
FairMQProgOptions::FairMQProgOptions()
|
||||
: FairProgOptions()
|
||||
, fMQCmdOptions("FairMQ device options")
|
||||
, fMQParserOptions("FairMQ config parser options")
|
||||
, fFairMQMap()
|
||||
: fVarMap()
|
||||
, fFairMQChannelMap()
|
||||
, fAllOptions("FairMQ Command Line Options")
|
||||
, fGeneralOptions("General options")
|
||||
, fMQOptions("FairMQ device options")
|
||||
, fParserOptions("FairMQ channel config parser options")
|
||||
, fConfigMutex()
|
||||
, fChannelInfo()
|
||||
, fMQKeyMap()
|
||||
, fChannelKeyMap()
|
||||
, fUnregisteredOptions()
|
||||
, fEvents()
|
||||
{
|
||||
InitOptionDescription();
|
||||
fGeneralOptions.add_options()
|
||||
("help,h", "Print help")
|
||||
("version,v", "Print version")
|
||||
("severity", po::value<string>()->default_value("debug"), "Log severity level: trace, debug, info, state, warn, error, fatal, nolog")
|
||||
("verbosity", po::value<string>()->default_value("medium"), "Log verbosity level: veryhigh, high, medium, low")
|
||||
("color", po::value<bool >()->default_value(true), "Log color (true/false)")
|
||||
("log-to-file", po::value<string>()->default_value(""), "Log output to a file.")
|
||||
("print-options", po::value<bool >()->implicit_value(true), "Print options in machine-readable format (<option>:<computed-value>:<type>:<description>)");
|
||||
|
||||
fMQOptions.add_options()
|
||||
("id", po::value<string>(), "Device ID (required argument).")
|
||||
("io-threads", po::value<int >()->default_value(1), "Number of I/O threads.")
|
||||
("transport", po::value<string>()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg'/'shmem') .")
|
||||
("network-interface", po::value<string>()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).")
|
||||
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file.")
|
||||
("initialization-timeout", po::value<int >()->default_value(120), "Timeout for the initialization in seconds (when expecting dynamic initialization).")
|
||||
("port-range-min", po::value<int >()->default_value(22000), "Start of the port range for dynamic initialization.")
|
||||
("port-range-max", po::value<int >()->default_value(32000), "End of the port range for dynamic initialization.")
|
||||
("print-channels", po::value<bool >()->implicit_value(true), "Print registered channel endpoints in a machine-readable format (<channel name>:<min num subchannels>:<max num subchannels>)")
|
||||
("shm-segment-size", po::value<size_t>()->default_value(2000000000), "Shared memory: size of the shared memory segment (in bytes).")
|
||||
("shm-monitor", po::value<bool >()->default_value(true), "Shared memory: run monitor daemon.")
|
||||
("rate", po::value<float >()->default_value(0.), "Rate for conditional run loop (Hz).")
|
||||
("session", po::value<string>()->default_value("default"), "Session name.");
|
||||
|
||||
fParserOptions.add_options()
|
||||
("mq-config", po::value<string>(), "JSON input as file.")
|
||||
("channel-config", po::value<vector<string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list");
|
||||
|
||||
fAllOptions.add(fGeneralOptions);
|
||||
fAllOptions.add(fMQOptions);
|
||||
fAllOptions.add(fParserOptions);
|
||||
|
||||
ParseDefaults();
|
||||
}
|
||||
|
||||
@@ -52,12 +97,20 @@ int FairMQProgOptions::ParseAll(const vector<string>& cmdLineArgs, bool allowUnr
|
||||
|
||||
int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
{
|
||||
if (FairProgOptions::ParseCmdLine(argc, argv, allowUnregistered))
|
||||
ParseCmdLine(argc, argv, allowUnregistered);
|
||||
|
||||
// if this option is provided, handle them and return stop value
|
||||
if (fVarMap.count("help"))
|
||||
{
|
||||
// ParseCmdLine returns 0 if no immediate switches found.
|
||||
cout << fAllOptions << endl;
|
||||
return 1;
|
||||
}
|
||||
// if this option is provided, handle them and return stop value
|
||||
if (fVarMap.count("print-options"))
|
||||
{
|
||||
PrintOptionsRaw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if these options are provided, do no further checks and let the device handle them
|
||||
if (fVarMap.count("print-channels") || fVarMap.count("version"))
|
||||
{
|
||||
@@ -90,7 +143,7 @@ int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool al
|
||||
{
|
||||
id = fVarMap["config-key"].as<string>();
|
||||
}
|
||||
else
|
||||
else if (fVarMap.count("id"))
|
||||
{
|
||||
id = fVarMap["id"].as<string>();
|
||||
}
|
||||
@@ -101,54 +154,84 @@ int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool al
|
||||
if (fVarMap.count("mq-config"))
|
||||
{
|
||||
LOG(debug) << "mq-config: Using default JSON parser";
|
||||
Store(fair::mq::parser::JSON().UserParser(fVarMap["mq-config"].as<string>(), id));
|
||||
}
|
||||
else if (fVarMap.count("config-json-string"))
|
||||
{
|
||||
LOG(debug) << "config-json-string: Parsing JSON string";
|
||||
string value = fair::mq::ConvertVariableValue<fair::mq::VarInfoToString>()(fVarMap.at("config-json-string"));
|
||||
stringstream ss;
|
||||
ss << value;
|
||||
Store(fair::mq::parser::JSON().UserParser(ss, id));
|
||||
UpdateChannelMap(parser::JSON().UserParser(fVarMap.at("mq-config").as<string>(), id));
|
||||
}
|
||||
else if (fVarMap.count("channel-config"))
|
||||
{
|
||||
LOG(debug) << "channel-config: Parsing channel configuration";
|
||||
Store(fair::mq::parser::SUBOPT().UserParser(fVarMap.at("channel-config").as<vector<string>>(), id));
|
||||
UpdateChannelMap(parser::SUBOPT().UserParser(fVarMap.at("channel-config").as<vector<string>>(), id));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(warn) << "FairMQProgOptions: no channels configuration provided via neither of:";
|
||||
for (const auto& p : fMQParserOptions.options())
|
||||
for (const auto& p : fParserOptions.options())
|
||||
{
|
||||
LOG(warn) << "--" << p->canonical_display_name();
|
||||
}
|
||||
LOG(warn) << "No channels will be created (You can create them manually).";
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << e.what();
|
||||
return 1;
|
||||
}
|
||||
|
||||
FairProgOptions::PrintOptions();
|
||||
PrintOptions();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairMQProgOptions::Store(const FairMQMap& channels)
|
||||
void FairMQProgOptions::ParseCmdLine(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
{
|
||||
fFairMQMap = channels;
|
||||
UpdateChannelInfo();
|
||||
UpdateMQValues();
|
||||
return 0;
|
||||
// get options from cmd line and store in variable map
|
||||
// here we use command_line_parser instead of parse_command_line, to allow unregistered and positional options
|
||||
if (allowUnregistered)
|
||||
{
|
||||
po::command_line_parser parser{argc, argv};
|
||||
parser.options(fAllOptions).allow_unregistered();
|
||||
po::parsed_options parsed = parser.run();
|
||||
fUnregisteredOptions = po::collect_unrecognized(parsed.options, po::include_positional);
|
||||
|
||||
po::store(parsed, fVarMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
po::store(po::parse_command_line(argc, argv, fAllOptions), fVarMap);
|
||||
}
|
||||
|
||||
po::notify(fVarMap);
|
||||
}
|
||||
|
||||
void FairMQProgOptions::ParseDefaults()
|
||||
{
|
||||
vector<string> emptyArgs;
|
||||
emptyArgs.push_back("dummy");
|
||||
|
||||
vector<const char*> argv(emptyArgs.size());
|
||||
|
||||
transform(emptyArgs.begin(), emptyArgs.end(), argv.begin(), [](const string& str)
|
||||
{
|
||||
return str.c_str();
|
||||
});
|
||||
|
||||
po::store(po::parse_command_line(argv.size(), const_cast<char**>(argv.data()), fAllOptions), fVarMap);
|
||||
}
|
||||
|
||||
unordered_map<string, vector<FairMQChannel>> FairMQProgOptions::GetFairMQMap() const
|
||||
{
|
||||
return fFairMQChannelMap;
|
||||
}
|
||||
|
||||
unordered_map<string, int> FairMQProgOptions::GetChannelInfo() const
|
||||
{
|
||||
return fChannelInfo;
|
||||
}
|
||||
|
||||
// replace FairMQChannelMap, and update variable map accordingly
|
||||
int FairMQProgOptions::UpdateChannelMap(const FairMQMap& channels)
|
||||
int FairMQProgOptions::UpdateChannelMap(const unordered_map<string, vector<FairMQChannel>>& channels)
|
||||
{
|
||||
fFairMQMap = channels;
|
||||
fFairMQChannelMap = channels;
|
||||
UpdateChannelInfo();
|
||||
UpdateMQValues();
|
||||
return 0;
|
||||
@@ -157,7 +240,7 @@ int FairMQProgOptions::UpdateChannelMap(const FairMQMap& channels)
|
||||
void FairMQProgOptions::UpdateChannelInfo()
|
||||
{
|
||||
fChannelInfo.clear();
|
||||
for (const auto& c : fFairMQMap)
|
||||
for (const auto& c : fFairMQChannelMap)
|
||||
{
|
||||
fChannelInfo.insert(make_pair(c.first, c.second.size()));
|
||||
}
|
||||
@@ -167,7 +250,7 @@ void FairMQProgOptions::UpdateChannelInfo()
|
||||
// create key for variable map as follow : channelName.index.memberName
|
||||
void FairMQProgOptions::UpdateMQValues()
|
||||
{
|
||||
for (const auto& p : fFairMQMap)
|
||||
for (const auto& p : fFairMQChannelMap)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -183,20 +266,20 @@ void FairMQProgOptions::UpdateMQValues()
|
||||
string rcvKernelSizeKey = "chans." + p.first + "." + to_string(index) + ".rcvKernelSize";
|
||||
string rateLoggingKey = "chans." + p.first + "." + to_string(index) + ".rateLogging";
|
||||
|
||||
fMQKeyMap[typeKey] = MQKey{p.first, index, "type"};
|
||||
fMQKeyMap[methodKey] = MQKey{p.first, index, "method"};
|
||||
fMQKeyMap[addressKey] = MQKey{p.first, index, "address"};
|
||||
fMQKeyMap[transportKey] = MQKey{p.first, index, "transport"};
|
||||
fMQKeyMap[sndBufSizeKey] = MQKey{p.first, index, "sndBufSize"};
|
||||
fMQKeyMap[rcvBufSizeKey] = MQKey{p.first, index, "rcvBufSize"};
|
||||
fMQKeyMap[sndKernelSizeKey] = MQKey{p.first, index, "sndKernelSize"};
|
||||
fMQKeyMap[rcvKernelSizeKey] = MQKey{p.first, index, "rcvkernelSize"};
|
||||
fMQKeyMap[rateLoggingKey] = MQKey{p.first, index, "rateLogging"};
|
||||
fChannelKeyMap[typeKey] = ChannelKey{p.first, index, "type"};
|
||||
fChannelKeyMap[methodKey] = ChannelKey{p.first, index, "method"};
|
||||
fChannelKeyMap[addressKey] = ChannelKey{p.first, index, "address"};
|
||||
fChannelKeyMap[transportKey] = ChannelKey{p.first, index, "transport"};
|
||||
fChannelKeyMap[sndBufSizeKey] = ChannelKey{p.first, index, "sndBufSize"};
|
||||
fChannelKeyMap[rcvBufSizeKey] = ChannelKey{p.first, index, "rcvBufSize"};
|
||||
fChannelKeyMap[sndKernelSizeKey] = ChannelKey{p.first, index, "sndKernelSize"};
|
||||
fChannelKeyMap[rcvKernelSizeKey] = ChannelKey{p.first, index, "rcvkernelSize"};
|
||||
fChannelKeyMap[rateLoggingKey] = ChannelKey{p.first, index, "rateLogging"};
|
||||
|
||||
UpdateVarMap<string>(typeKey, channel.GetType());
|
||||
UpdateVarMap<string>(methodKey, channel.GetMethod());
|
||||
UpdateVarMap<string>(addressKey, channel.GetAddress());
|
||||
UpdateVarMap<string>(transportKey, channel.GetTransport());
|
||||
UpdateVarMap<string>(transportKey, channel.GetTransportName());
|
||||
UpdateVarMap<int>(sndBufSizeKey, channel.GetSndBufSize());
|
||||
UpdateVarMap<int>(rcvBufSizeKey, channel.GetRcvBufSize());
|
||||
UpdateVarMap<int>(sndKernelSizeKey, channel.GetSndKernelSize());
|
||||
@@ -209,103 +292,56 @@ void FairMQProgOptions::UpdateMQValues()
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQProgOptions::ImmediateOptions()
|
||||
{
|
||||
if (fVarMap.count("help"))
|
||||
{
|
||||
cout << "===== FairMQ Program Options =====" << endl << fAllOptions;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fVarMap.count("print-options"))
|
||||
{
|
||||
PrintOptionsRaw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FairMQProgOptions::InitOptionDescription()
|
||||
{
|
||||
fMQCmdOptions.add_options()
|
||||
("id", po::value<string>(), "Device ID (required argument).")
|
||||
("io-threads", po::value<int >()->default_value(1), "Number of I/O threads.")
|
||||
("transport", po::value<string>()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').")
|
||||
("config", po::value<string>()->default_value("static"), "Config source ('static'/<config library filename>).")
|
||||
("network-interface", po::value<string>()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).")
|
||||
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file.")
|
||||
("initialization-timeout", po::value<int >()->default_value(120), "Timeout for the initialization in seconds (when expecting dynamic initialization).")
|
||||
("port-range-min", po::value<int >()->default_value(22000), "Start of the port range for dynamic initialization.")
|
||||
("port-range-max", po::value<int >()->default_value(32000), "End of the port range for dynamic initialization.")
|
||||
("print-channels", po::value<bool >()->implicit_value(true), "Print registered channel endpoints in a machine-readable format (<channel name>:<min num subchannels>:<max num subchannels>)")
|
||||
("shm-segment-size", po::value<size_t>()->default_value(2000000000), "Shared memory: size of the shared memory segment (in bytes).")
|
||||
("shm-monitor", po::value<bool >()->default_value(true), "Shared memory: run monitor daemon.")
|
||||
("rate", po::value<float >()->default_value(0.), "Rate for conditional run loop (Hz).")
|
||||
("session", po::value<string>()->default_value("default"), "Session name.")
|
||||
;
|
||||
|
||||
fMQParserOptions.add_options()
|
||||
("config-json-string", po::value<vector<string>>()->multitoken(), "JSON input as command line string.")
|
||||
("mq-config", po::value<string>(), "JSON/XML input as file. The configuration object will check xml or json file extention and will call the json or xml parser accordingly")
|
||||
("channel-config", po::value<vector<string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
||||
;
|
||||
|
||||
AddToCmdLineOptions(fMQCmdOptions);
|
||||
AddToCmdLineOptions(fMQParserOptions);
|
||||
}
|
||||
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, const string& val)
|
||||
int FairMQProgOptions::UpdateChannelValue(const string& channelName, int index, const string& member, const string& val)
|
||||
{
|
||||
if (member == "type")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateType(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateType(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "method")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateMethod(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateMethod(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "address")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateAddress(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateAddress(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "transport")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateTransport(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateTransport(val);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if we get there it means something is wrong
|
||||
LOG(error) << "update of FairMQChannel map failed for the following key: "
|
||||
<< channelName << "." << index << "." << member;
|
||||
LOG(error) << "update of FairMQChannel map failed for the following key: " << channelName << "." << index << "." << member;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, int val)
|
||||
int FairMQProgOptions::UpdateChannelValue(const string& channelName, int index, const string& member, int val)
|
||||
{
|
||||
if (member == "sndBufSize")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateSndBufSize(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateSndBufSize(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "rcvBufSize")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateRcvBufSize(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateRcvBufSize(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "rateLogging")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateRateLogging(val);
|
||||
fFairMQChannelMap.at(channelName).at(index).UpdateRateLogging(val);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -315,3 +351,135 @@ int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, co
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> FairMQProgOptions::GetPropertyKeys() const
|
||||
{
|
||||
lock_guard<mutex> lock{fConfigMutex};
|
||||
|
||||
vector<string> result;
|
||||
|
||||
for (const auto& it : fVarMap)
|
||||
{
|
||||
result.push_back(it.first.c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Add option descriptions
|
||||
int FairMQProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool /* visible */)
|
||||
{
|
||||
fAllOptions.add(optDesc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
po::options_description& FairMQProgOptions::GetCmdLineOptions()
|
||||
{
|
||||
return fAllOptions;
|
||||
}
|
||||
|
||||
int FairMQProgOptions::PrintOptions()
|
||||
{
|
||||
// -> loop over variable map and print its content
|
||||
// -> In this example the following types are supported:
|
||||
// string, int, float, double, short, boost::filesystem::path
|
||||
// vector<string>, vector<int>, vector<float>, vector<double>, vector<short>
|
||||
|
||||
map<string, VarValInfo> mapinfo;
|
||||
|
||||
// get string length for formatting and convert varmap values into string
|
||||
int maxLenKey = 0;
|
||||
int maxLenValue = 0;
|
||||
int maxLenType = 0;
|
||||
int maxLenDefault = 0;
|
||||
|
||||
for (const auto& m : fVarMap)
|
||||
{
|
||||
maxLenKey = max(maxLenKey, static_cast<int>(m.first.length()));
|
||||
|
||||
VarValInfo valinfo = ConvertVariableValue<options::ToVarValInfo>()((m.second));
|
||||
mapinfo[m.first] = valinfo;
|
||||
|
||||
maxLenValue = max(maxLenValue, static_cast<int>(valinfo.value.length()));
|
||||
maxLenType = max(maxLenType, static_cast<int>(valinfo.type.length()));
|
||||
maxLenDefault = max(maxLenDefault, static_cast<int>(valinfo.defaulted.length()));
|
||||
}
|
||||
|
||||
// TODO : limit the value len field in a better way
|
||||
if (maxLenValue > 100)
|
||||
{
|
||||
maxLenValue = 100;
|
||||
}
|
||||
|
||||
for (const auto& o : fUnregisteredOptions)
|
||||
{
|
||||
LOG(debug) << "detected unregistered option: " << o;
|
||||
}
|
||||
|
||||
stringstream ss;
|
||||
ss << "Configuration: \n";
|
||||
|
||||
for (const auto& p : mapinfo)
|
||||
{
|
||||
ss << setfill(' ') << left
|
||||
<< setw(maxLenKey) << p.first << " = "
|
||||
<< setw(maxLenValue) << p.second.value
|
||||
<< setw(maxLenType) << p.second.type
|
||||
<< setw(maxLenDefault) << p.second.defaulted
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
LOG(info) << ss.str();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairMQProgOptions::PrintOptionsRaw()
|
||||
{
|
||||
const vector<boost::shared_ptr<po::option_description>>& options = fAllOptions.options();
|
||||
|
||||
for (const auto& o : options)
|
||||
{
|
||||
VarValInfo value;
|
||||
if (fVarMap.count(o->canonical_display_name()))
|
||||
{
|
||||
value = ConvertVariableValue<options::ToVarValInfo>()((fVarMap[o->canonical_display_name()]));
|
||||
}
|
||||
|
||||
string description = o->description();
|
||||
|
||||
replace(description.begin(), description.end(), '\n', ' ');
|
||||
|
||||
cout << o->long_name() << ":" << value.value << ":" << (value.type == "" ? "<unknown>" : value.type) << ":" << description << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string FairMQProgOptions::GetStringValue(const string& key)
|
||||
{
|
||||
unique_lock<mutex> lock(fConfigMutex);
|
||||
|
||||
string valueStr;
|
||||
try
|
||||
{
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
valueStr = ConvertVariableValue<options::ToString>()(fVarMap.at(key));
|
||||
}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << "Exception thrown for the key '" << key << "'";
|
||||
LOG(error) << e.what();
|
||||
}
|
||||
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
int FairMQProgOptions::Count(const string& key) const
|
||||
{
|
||||
unique_lock<mutex> lock(fConfigMutex);
|
||||
|
||||
return fVarMap.count(key);
|
||||
}
|
||||
|
@@ -6,26 +6,22 @@
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
/*
|
||||
* File: FairMQProgOptions.h
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on March 11, 2015, 10:20 PM
|
||||
*/
|
||||
|
||||
#ifndef FAIRMQPROGOPTIONS_H
|
||||
#define FAIRMQPROGOPTIONS_H
|
||||
|
||||
#include <fairmq/EventManager.h>
|
||||
|
||||
#include "FairProgOptions.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairMQChannel.h"
|
||||
#include <fairmq/Tools.h>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
@@ -38,10 +34,10 @@ struct PropertyChangeAsString : Event<std::string> {};
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
|
||||
class FairMQProgOptions : public FairProgOptions
|
||||
class FairMQProgOptions
|
||||
{
|
||||
protected:
|
||||
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
private:
|
||||
using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
|
||||
public:
|
||||
FairMQProgOptions();
|
||||
@@ -49,52 +45,11 @@ class FairMQProgOptions : public FairProgOptions
|
||||
|
||||
int ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
||||
// parse command line.
|
||||
// default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
|
||||
int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override;
|
||||
// default parser for the mq-configuration file (JSON) is called if command line key mq-config is called
|
||||
int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = true);
|
||||
|
||||
FairMQMap GetFairMQMap() const
|
||||
{
|
||||
return fFairMQMap;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, int> GetChannelInfo() const
|
||||
{
|
||||
return fChannelInfo;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int UpdateValue(const std::string& key, T val)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fConfigMutex);
|
||||
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
// update variable map
|
||||
UpdateVarMap<typename std::decay<T>::type>(key, val);
|
||||
|
||||
// update FairMQChannel map, check first if data are int or string
|
||||
if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)
|
||||
{
|
||||
if (fMQKeyMap.count(key))
|
||||
{
|
||||
UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val);
|
||||
}
|
||||
}
|
||||
|
||||
lock.unlock();
|
||||
//if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)//if one wants to restrict type
|
||||
fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
|
||||
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetStringValue(key));
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "UpdateValue failed: key '" << key << "' not found in the variable map";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
FairMQChannelMap GetFairMQMap() const;
|
||||
std::unordered_map<std::string, int> GetChannelInfo() const;
|
||||
|
||||
template<typename T>
|
||||
int SetValue(const std::string& key, T val)
|
||||
@@ -104,12 +59,12 @@ class FairMQProgOptions : public FairProgOptions
|
||||
// update variable map
|
||||
UpdateVarMap<typename std::decay<T>::type>(key, val);
|
||||
|
||||
// update FairMQChannel map, check first if data are int or string
|
||||
// update FairMQChannel map if the key is a channel key
|
||||
if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)
|
||||
{
|
||||
if (fMQKeyMap.count(key))
|
||||
if (fChannelKeyMap.count(key))
|
||||
{
|
||||
UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val);
|
||||
UpdateChannelValue(fChannelKeyMap.at(key).channel, fChannelKeyMap.at(key).index, fChannelKeyMap.at(key).member, val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,57 +110,114 @@ class FairMQProgOptions : public FairProgOptions
|
||||
fEvents.Unsubscribe<fair::mq::PropertyChangeAsString, std::string>(subscriber);
|
||||
}
|
||||
|
||||
// replace FairMQChannelMap, and update variable map accordingly
|
||||
int UpdateChannelMap(const FairMQMap& map);
|
||||
std::vector<std::string> GetPropertyKeys() const;
|
||||
|
||||
protected:
|
||||
struct MQKey
|
||||
// get value corresponding to the key
|
||||
template<typename T>
|
||||
T GetValue(const std::string& key) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fConfigMutex);
|
||||
|
||||
T val = T();
|
||||
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
val = fVarMap[key].as<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(warn) << "Config has no key: " << key << ". Returning default constructed object.";
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
// Given a key, convert the variable value to string
|
||||
std::string GetStringValue(const std::string& key);
|
||||
|
||||
int Count(const std::string& key) const;
|
||||
|
||||
template<typename T>
|
||||
T ConvertTo(const std::string& strValue)
|
||||
{
|
||||
if (std::is_arithmetic<T>::value)
|
||||
{
|
||||
std::istringstream iss(strValue);
|
||||
T val;
|
||||
iss >> val;
|
||||
return val;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "the provided string " << strValue << " cannot be converted to the requested type. The target type must be arithmetic type.";
|
||||
}
|
||||
}
|
||||
|
||||
// add options_description
|
||||
int AddToCmdLineOptions(const boost::program_options::options_description optDesc, bool visible = true);
|
||||
boost::program_options::options_description& GetCmdLineOptions();
|
||||
|
||||
const boost::program_options::variables_map& GetVarMap() const { return fVarMap; }
|
||||
|
||||
int PrintOptions();
|
||||
int PrintOptionsRaw();
|
||||
|
||||
private:
|
||||
struct ChannelKey
|
||||
{
|
||||
std::string channel;
|
||||
int index;
|
||||
std::string member;
|
||||
};
|
||||
|
||||
po::options_description fMQCmdOptions;
|
||||
po::options_description fMQParserOptions;
|
||||
FairMQMap fFairMQMap;
|
||||
boost::program_options::variables_map fVarMap; ///< options container
|
||||
FairMQChannelMap fFairMQChannelMap;
|
||||
|
||||
// map of read channel info - channel name - number of subchannels
|
||||
std::unordered_map<std::string, int> fChannelInfo;
|
||||
boost::program_options::options_description fAllOptions; ///< all options descriptions
|
||||
boost::program_options::options_description fGeneralOptions; ///< general options descriptions
|
||||
boost::program_options::options_description fMQOptions; ///< MQ options descriptions
|
||||
boost::program_options::options_description fParserOptions; ///< MQ Parser options descriptions
|
||||
|
||||
std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=key info
|
||||
mutable std::mutex fConfigMutex;
|
||||
|
||||
int ImmediateOptions() override; // for custom help & version printing
|
||||
void InitOptionDescription();
|
||||
std::unordered_map<std::string, int> fChannelInfo; ///< channel name - number of subchannels
|
||||
std::unordered_map<std::string, ChannelKey> fChannelKeyMap;// key=full path - val=key info
|
||||
std::vector<std::string> fUnregisteredOptions; ///< container with unregistered options
|
||||
|
||||
fair::mq::EventManager fEvents;
|
||||
|
||||
void ParseCmdLine(const int argc, char const* const* argv, bool allowUnregistered = true);
|
||||
void ParseDefaults();
|
||||
|
||||
// read FairMQChannelMap and insert/update corresponding values in variable map
|
||||
// create key for variable map as follow : channelName.index.memberName
|
||||
void UpdateMQValues();
|
||||
int Store(const FairMQMap& channels);
|
||||
int Store(const FairMQChannelMap& channels);
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
void EmitUpdate(const std::string& key, T val)
|
||||
{
|
||||
//compile time check whether T is const char* or char*, and in that case a compile time error is thrown.
|
||||
// compile time check whether T is const char* or char*, and in that case a compile time error is thrown.
|
||||
static_assert(!std::is_same<T,const char*>::value || !std::is_same<T, char*>::value,
|
||||
"In template member FairMQProgOptions::EmitUpdate<T>(key,val) the types const char* or char* for the calback signatures are not supported.");
|
||||
fEvents.Emit<fair::mq::PropertyChange, T>(key, val);
|
||||
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetStringValue(key));
|
||||
}
|
||||
|
||||
int UpdateChannelMap(const std::string& channelName, int index, const std::string& member, const std::string& val);
|
||||
int UpdateChannelMap(const std::string& channelName, int index, const std::string& member, int val);
|
||||
// for cases other than int and string
|
||||
template<typename T>
|
||||
int UpdateChannelMap(const std::string& /*channelName*/, int /*index*/, const std::string& /*member*/, T /*val*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int UpdateChannelMap(const FairMQChannelMap& map);
|
||||
int UpdateChannelValue(const std::string& channelName, int index, const std::string& member, const std::string& val);
|
||||
int UpdateChannelValue(const std::string& channelName, int index, const std::string& member, int val);
|
||||
|
||||
void UpdateChannelInfo();
|
||||
|
||||
fair::mq::EventManager fEvents;
|
||||
// helper to modify the value of variable map after calling boost::program_options::store
|
||||
template<typename T>
|
||||
void UpdateVarMap(const std::string& key, const T& val)
|
||||
{
|
||||
std::map<std::string, boost::program_options::variable_value>& vm = fVarMap;
|
||||
vm[key].value() = boost::any(val);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif /* FAIRMQPROGOPTIONS_H */
|
||||
|
@@ -29,7 +29,7 @@ namespace parser
|
||||
|
||||
constexpr const char* SUBOPT::channelOptionKeys[];
|
||||
|
||||
FairMQMap SUBOPT::UserParser(const vector<string>& channelConfig, const string& deviceId, const string& rootNode)
|
||||
FairMQChannelMap SUBOPT::UserParser(const vector<string>& channelConfig, const string& deviceId, const string& rootNode)
|
||||
{
|
||||
ptree pt;
|
||||
|
||||
|
@@ -14,14 +14,12 @@
|
||||
#ifndef FAIRMQPARSER_SUBOPT_H
|
||||
#define FAIRMQPARSER_SUBOPT_H
|
||||
|
||||
#include "FairMQParser.h" // for FairMQMap
|
||||
#include "FairMQParser.h" // for FairMQChannelMap
|
||||
#include <boost/program_options.hpp>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
@@ -78,7 +76,7 @@ struct SUBOPT
|
||||
nullptr
|
||||
};
|
||||
|
||||
FairMQMap UserParser(const std::vector<std::string>& channelConfig, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||
FairMQChannelMap UserParser(const std::vector<std::string>& channelConfig, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -1,178 +0,0 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/*
|
||||
* File: FairProgOptions.cxx
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on March 11, 2015, 5:38 PM
|
||||
*/
|
||||
|
||||
#include "FairProgOptions.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq;
|
||||
|
||||
FairProgOptions::FairProgOptions()
|
||||
: fVarMap()
|
||||
, fGeneralOptions("General options")
|
||||
, fAllOptions("Command line options")
|
||||
, fConfigMutex()
|
||||
{
|
||||
fGeneralOptions.add_options()
|
||||
("help,h", "produce help")
|
||||
("version,v", "print version")
|
||||
("severity", po::value<string>()->default_value("debug"), "Log severity level: trace, debug, info, state, warn, error, fatal, nolog")
|
||||
("verbosity", po::value<string>()->default_value("medium"), "Log verbosity level: veryhigh, high, medium, low")
|
||||
("color", po::value<bool>()->default_value(true), "Log color (true/false)")
|
||||
("log-to-file", po::value<string>()->default_value(""), "Log output to a file.")
|
||||
("print-options", po::value<bool>()->implicit_value(true), "print options in machine-readable format (<option>:<computed-value>:<type>:<description>)");
|
||||
|
||||
fAllOptions.add(fGeneralOptions);
|
||||
}
|
||||
|
||||
FairProgOptions::~FairProgOptions()
|
||||
{
|
||||
}
|
||||
|
||||
/// Add option descriptions
|
||||
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool /* visible */)
|
||||
{
|
||||
fAllOptions.add(optDesc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
po::options_description& FairProgOptions::GetCmdLineOptions()
|
||||
{
|
||||
return fAllOptions;
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
{
|
||||
// get options from cmd line and store in variable map
|
||||
// here we use command_line_parser instead of parse_command_line, to allow unregistered and positional options
|
||||
if (allowUnregistered)
|
||||
{
|
||||
po::command_line_parser parser{argc, argv};
|
||||
parser.options(fAllOptions).allow_unregistered();
|
||||
po::parsed_options parsedOptions = parser.run();
|
||||
po::store(parsedOptions, fVarMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
po::store(po::parse_command_line(argc, argv, fAllOptions), fVarMap);
|
||||
}
|
||||
|
||||
// Handles options like "--help" or "--version"
|
||||
// return 1 if switch options found in fVarMap
|
||||
if (ImmediateOptions())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
po::notify(fVarMap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FairProgOptions::ParseDefaults()
|
||||
{
|
||||
vector<string> emptyArgs;
|
||||
emptyArgs.push_back("dummy");
|
||||
|
||||
vector<const char*> argv(emptyArgs.size());
|
||||
|
||||
transform(emptyArgs.begin(), emptyArgs.end(), argv.begin(), [](const string& str)
|
||||
{
|
||||
return str.c_str();
|
||||
});
|
||||
|
||||
po::store(po::parse_command_line(argv.size(), const_cast<char**>(argv.data()), fAllOptions), fVarMap);
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintOptions()
|
||||
{
|
||||
// -> loop over variable map and print its content
|
||||
// -> In this example the following types are supported:
|
||||
// string, int, float, double, short, boost::filesystem::path
|
||||
// vector<string>, vector<int>, vector<float>, vector<double>, vector<short>
|
||||
|
||||
map<string, VarValInfo> mapinfo;
|
||||
|
||||
// get string length for formatting and convert varmap values into string
|
||||
int maxLen1st = 0;
|
||||
int maxLen2nd = 0;
|
||||
int maxLenTypeInfo = 0;
|
||||
int maxLenDefault = 0;
|
||||
int maxLenEmpty = 0;
|
||||
for (const auto& m : fVarMap)
|
||||
{
|
||||
Max(maxLen1st, m.first.length());
|
||||
|
||||
VarValInfo valinfo = GetVariableValueInfo(m.second);
|
||||
mapinfo[m.first] = valinfo;
|
||||
|
||||
Max(maxLen2nd, valinfo.value.length());
|
||||
Max(maxLenTypeInfo, valinfo.type.length());
|
||||
Max(maxLenDefault, valinfo.defaulted.length());
|
||||
Max(maxLenEmpty, valinfo.empty.length());
|
||||
}
|
||||
|
||||
// TODO : limit the value len field in a better way
|
||||
if (maxLen2nd > 100)
|
||||
{
|
||||
maxLen2nd = 100;
|
||||
}
|
||||
|
||||
stringstream ss;
|
||||
ss << "Configuration: \n";
|
||||
|
||||
for (const auto& p : mapinfo)
|
||||
{
|
||||
ss << setfill(' ')
|
||||
<< setw(maxLen1st) << left << p.first << " = "
|
||||
<< setw(maxLen2nd) << p.second.value
|
||||
<< setw(maxLenTypeInfo) << p.second.type
|
||||
<< setw(maxLenDefault) << p.second.defaulted
|
||||
<< setw(maxLenEmpty) << p.second.empty
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
LOG(info) << ss.str();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintOptionsRaw()
|
||||
{
|
||||
const std::vector<boost::shared_ptr<po::option_description>>& options = fAllOptions.options();
|
||||
|
||||
for (const auto& o : options)
|
||||
{
|
||||
VarValInfo value;
|
||||
if (fVarMap.count(o->canonical_display_name()))
|
||||
{
|
||||
value = GetVariableValueInfo(fVarMap[o->canonical_display_name()]);
|
||||
}
|
||||
|
||||
string description = o->description();
|
||||
|
||||
replace(description.begin(), description.end(), '\n', ' ');
|
||||
|
||||
cout << o->long_name() << ":" << value.value << ":" << (value.type == "" ? "<unknown>" : value.type) << ":" << description << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VarValInfo FairProgOptions::GetVariableValueInfo(const po::variable_value& varValue)
|
||||
{
|
||||
return ConvertVariableValue<ToVarValInfo>()(varValue);
|
||||
}
|
@@ -1,172 +1 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
/*
|
||||
* File: FairProgOptions.h
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on March 11, 2015, 5:38 PM
|
||||
*/
|
||||
|
||||
#ifndef FAIRPROGOPTIONS_H
|
||||
#define FAIRPROGOPTIONS_H
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairProgOptionsHelper.h"
|
||||
#include <fairmq/Tools.h>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <exception>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
class FairProgOptions
|
||||
{
|
||||
public:
|
||||
FairProgOptions();
|
||||
virtual ~FairProgOptions();
|
||||
|
||||
auto GetPropertyKeys() const -> std::vector<std::string>
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{fConfigMutex};
|
||||
|
||||
std::vector<std::string> result;
|
||||
|
||||
for (const auto& it : fVarMap)
|
||||
{
|
||||
result.push_back(it.first.c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// add options_description
|
||||
int AddToCmdLineOptions(const po::options_description optDesc, bool visible = true);
|
||||
po::options_description& GetCmdLineOptions();
|
||||
|
||||
// get value corresponding to the key
|
||||
template<typename T>
|
||||
T GetValue(const std::string& key) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fConfigMutex);
|
||||
|
||||
T val = T();
|
||||
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
val = fVarMap[key].as<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(warn) << "Config has no key: " << key << ". Returning default constructed object.";
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
// Given a key, convert the variable value to string
|
||||
std::string GetStringValue(const std::string& key)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fConfigMutex);
|
||||
|
||||
std::string valueStr;
|
||||
try
|
||||
{
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
valueStr = fair::mq::ConvertVariableValue<fair::mq::VarInfoToString>()(fVarMap.at(key));
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(error) << "Exception thrown for the key '" << key << "'";
|
||||
LOG(error) << e.what();
|
||||
}
|
||||
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
int Count(const std::string& key) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(fConfigMutex);
|
||||
|
||||
return fVarMap.count(key);
|
||||
}
|
||||
|
||||
//restrict conversion to fundamental types
|
||||
template<typename T>
|
||||
T ConvertTo(const std::string& strValue)
|
||||
{
|
||||
if (std::is_arithmetic<T>::value)
|
||||
{
|
||||
std::istringstream iss(strValue);
|
||||
T val;
|
||||
iss >> val;
|
||||
return val;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "the provided string " << strValue << " cannot be converted in the requested type. The target types must be arithmetic types";
|
||||
}
|
||||
}
|
||||
|
||||
const po::variables_map& GetVarMap() const { return fVarMap; }
|
||||
|
||||
int ParseCmdLine(const int argc, char const* const* argv, bool allowUnregistered = false);
|
||||
void ParseDefaults();
|
||||
|
||||
virtual int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;
|
||||
|
||||
virtual int PrintOptions();
|
||||
virtual int PrintOptionsRaw();
|
||||
|
||||
protected:
|
||||
// options container
|
||||
po::variables_map fVarMap;
|
||||
|
||||
// options descriptions
|
||||
po::options_description fGeneralOptions;
|
||||
po::options_description fAllOptions;
|
||||
|
||||
mutable std::mutex fConfigMutex;
|
||||
|
||||
virtual int ImmediateOptions() = 0;
|
||||
|
||||
// UpdateVarMap() and Replace() --> helper functions to modify the value of variable map after calling po::store
|
||||
template<typename T>
|
||||
void UpdateVarMap(const std::string& key, const T& val)
|
||||
{
|
||||
Replace(fVarMap, key, val);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Replace(std::map<std::string, po::variable_value>& vm, const std::string& key, const T& val)
|
||||
{
|
||||
vm[key].value() = boost::any(val);
|
||||
}
|
||||
|
||||
private:
|
||||
fair::mq::VarValInfo GetVariableValueInfo(const po::variable_value& varValue);
|
||||
|
||||
static void Max(int& val, const int& comp)
|
||||
{
|
||||
if (comp > val)
|
||||
{
|
||||
val = comp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FAIRPROGOPTIONS_H */
|
||||
#warning "This header file is deprecated. Use FairMQProgOptions class directly which now contains all FairProgOptions functionality. Note, that FairMQProgOptions is also available if you include FairMQDevice."
|
||||
|
@@ -17,211 +17,171 @@
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/spirit/home/support/detail/hold_any.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <iterator>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
|
||||
template<class T>
|
||||
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
|
||||
{
|
||||
for (const auto& i : v)
|
||||
{
|
||||
os << i << " ";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
struct VarValInfo
|
||||
{
|
||||
std::string value;
|
||||
std::string type;
|
||||
std::string defaulted;
|
||||
std::string empty;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
|
||||
{
|
||||
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(os, " "));
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool typeIs(const boost::program_options::variable_value& varValue)
|
||||
std::string ConvertVariableValueToString(const boost::program_options::variable_value& varVal)
|
||||
{
|
||||
auto& value = varValue.value();
|
||||
if (auto q = boost::any_cast<T>(&value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
std::ostringstream oss;
|
||||
if (auto q = boost::any_cast<T>(&varVal.value())) {
|
||||
oss << *q;
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string ConvertVariableValueToString(const boost::program_options::variable_value& varValue)
|
||||
namespace options
|
||||
{
|
||||
auto& value = varValue.value();
|
||||
std::ostringstream ostr;
|
||||
if (auto q = boost::any_cast<T>(&value))
|
||||
{
|
||||
ostr << *q;
|
||||
}
|
||||
std::string valueStr = ostr.str();
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
// string specialization
|
||||
template<>
|
||||
inline std::string ConvertVariableValueToString<std::string>(const boost::program_options::variable_value& varValue)
|
||||
{
|
||||
auto& value = varValue.value();
|
||||
std::string valueStr;
|
||||
if (auto q = boost::any_cast<std::string>(&value))
|
||||
{
|
||||
valueStr = *q;
|
||||
}
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
// boost::filesystem::path specialization
|
||||
template<>
|
||||
inline std::string ConvertVariableValueToString<boost::filesystem::path>(const boost::program_options::variable_value& varValue)
|
||||
{
|
||||
auto& value = varValue.value();
|
||||
std::string valueStr;
|
||||
if (auto q = boost::any_cast<boost::filesystem::path>(&value))
|
||||
{
|
||||
valueStr = (*q).string();
|
||||
}
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
// policy to convert boost variable value into string
|
||||
struct VarInfoToString
|
||||
struct ToString
|
||||
{
|
||||
using returned_type = std::string;
|
||||
|
||||
template<typename T>
|
||||
std::string Value(const boost::program_options::variable_value& varValue, const std::string&, const std::string&, const std::string&)
|
||||
std::string Value(const boost::program_options::variable_value& varVal, const std::string&, const std::string&)
|
||||
{
|
||||
return ConvertVariableValueToString<T>(varValue);
|
||||
return ConvertVariableValueToString<T>(varVal);
|
||||
}
|
||||
|
||||
returned_type DefaultValue(const std::string&, const std::string&)
|
||||
returned_type DefaultValue(const std::string&)
|
||||
{
|
||||
return std::string("empty value");
|
||||
return std::string("[unidentified]");
|
||||
}
|
||||
};
|
||||
|
||||
// policy to convert variable value content into VarValInfo
|
||||
struct ToVarValInfo
|
||||
{
|
||||
using returned_type = fair::mq::VarValInfo;
|
||||
using returned_type = VarValInfo;
|
||||
|
||||
template<typename T>
|
||||
returned_type Value(const boost::program_options::variable_value& varValue, const std::string& type, const std::string& defaulted, const std::string& empty)
|
||||
returned_type Value(const boost::program_options::variable_value& varVal, const std::string& type, const std::string& defaulted)
|
||||
{
|
||||
std::string valueStr = ConvertVariableValueToString<T>(varValue);
|
||||
return fair::mq::VarValInfo{valueStr, type, defaulted, empty};
|
||||
return VarValInfo{ConvertVariableValueToString<T>(varVal), type, defaulted};
|
||||
}
|
||||
|
||||
returned_type DefaultValue(const std::string& defaulted, const std::string& empty)
|
||||
returned_type DefaultValue(const std::string& defaulted)
|
||||
{
|
||||
return fair::mq::VarValInfo{std::string("Unknown value"), std::string(" [Unknown]"), defaulted, empty};
|
||||
return VarValInfo{std::string("[unidentified]"), std::string("[unidentified]"), defaulted};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace options
|
||||
|
||||
// host class that take one of the two policy defined above
|
||||
template<typename T>
|
||||
struct ConvertVariableValue : T
|
||||
{
|
||||
auto operator()(const boost::program_options::variable_value& varValue) -> typename T::returned_type
|
||||
auto operator()(const boost::program_options::variable_value& varVal) -> typename T::returned_type
|
||||
{
|
||||
std::string defaulted;
|
||||
std::string empty;
|
||||
|
||||
if (varValue.empty())
|
||||
if (varVal.defaulted())
|
||||
{
|
||||
empty = " [empty]";
|
||||
defaulted = " [default]";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varValue.defaulted())
|
||||
{
|
||||
defaulted = " [default]";
|
||||
}
|
||||
else
|
||||
{
|
||||
defaulted = " [provided]";
|
||||
}
|
||||
defaulted = " [provided]";
|
||||
}
|
||||
|
||||
if (typeIs<std::string>(varValue))
|
||||
return T::template Value<std::string>(varValue, std::string("<string>"), defaulted, empty);
|
||||
if (typeid(std::string) == varVal.value().type())
|
||||
return T::template Value<std::string>(varVal, std::string("<string>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<std::string>>(varValue))
|
||||
return T::template Value<std::vector<std::string>>(varValue, std::string("<vector<string>>"), defaulted, empty);
|
||||
if (typeid(std::vector<std::string>) == varVal.value().type())
|
||||
return T::template Value<std::vector<std::string>>(varVal, std::string("<vector<string>>"), defaulted);
|
||||
|
||||
if (typeIs<int>(varValue))
|
||||
return T::template Value<int>(varValue, std::string("<int>"), defaulted, empty);
|
||||
if (typeid(int) == varVal.value().type())
|
||||
return T::template Value<int>(varVal, std::string("<int>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<int>>(varValue))
|
||||
return T::template Value<std::vector<int>>(varValue, std::string("<vector<int>>"), defaulted, empty);
|
||||
if (typeid(std::vector<int>) == varVal.value().type())
|
||||
return T::template Value<std::vector<int>>(varVal, std::string("<vector<int>>"), defaulted);
|
||||
|
||||
if (typeIs<float>(varValue))
|
||||
return T::template Value<float>(varValue, std::string("<float>"), defaulted, empty);
|
||||
if (typeid(float) == varVal.value().type())
|
||||
return T::template Value<float>(varVal, std::string("<float>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<float>>(varValue))
|
||||
return T::template Value<std::vector<float>>(varValue, std::string("<vector<float>>"), defaulted, empty);
|
||||
if (typeid(std::vector<float>) == varVal.value().type())
|
||||
return T::template Value<std::vector<float>>(varVal, std::string("<vector<float>>"), defaulted);
|
||||
|
||||
if (typeIs<double>(varValue))
|
||||
return T::template Value<double>(varValue, std::string("<double>"), defaulted, empty);
|
||||
if (typeid(double) == varVal.value().type())
|
||||
return T::template Value<double>(varVal, std::string("<double>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<double>>(varValue))
|
||||
return T::template Value<std::vector<double>>(varValue, std::string("<vector<double>>"), defaulted, empty);
|
||||
if (typeid(std::vector<double>) == varVal.value().type())
|
||||
return T::template Value<std::vector<double>>(varVal, std::string("<vector<double>>"), defaulted);
|
||||
|
||||
if (typeIs<short>(varValue))
|
||||
return T::template Value<short>(varValue, std::string("<short>"), defaulted, empty);
|
||||
if (typeid(short) == varVal.value().type())
|
||||
return T::template Value<short>(varVal, std::string("<short>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<short>>(varValue))
|
||||
return T::template Value<std::vector<short>>(varValue, std::string("<vector<short>>"), defaulted, empty);
|
||||
if (typeid(std::vector<short>) == varVal.value().type())
|
||||
return T::template Value<std::vector<short>>(varVal, std::string("<vector<short>>"), defaulted);
|
||||
|
||||
if (typeIs<long>(varValue))
|
||||
return T::template Value<long>(varValue, std::string("<long>"), defaulted, empty);
|
||||
if (typeid(long) == varVal.value().type())
|
||||
return T::template Value<long>(varVal, std::string("<long>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<long>>(varValue))
|
||||
return T::template Value<std::vector<long>>(varValue, std::string("<vector<long>>"), defaulted, empty);
|
||||
if (typeid(std::vector<long>) == varVal.value().type())
|
||||
return T::template Value<std::vector<long>>(varVal, std::string("<vector<long>>"), defaulted);
|
||||
|
||||
if (typeIs<std::size_t>(varValue))
|
||||
return T::template Value<std::size_t>(varValue, std::string("<std::size_t>"), defaulted, empty);
|
||||
if (typeid(std::size_t) == varVal.value().type())
|
||||
return T::template Value<std::size_t>(varVal, std::string("<std::size_t>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<std::size_t>>(varValue))
|
||||
return T::template Value<std::vector<std::size_t>>(varValue, std::string("<vector<std::size_t>>"), defaulted, empty);
|
||||
if (typeid(std::vector<std::size_t>) == varVal.value().type())
|
||||
return T::template Value<std::vector<std::size_t>>(varVal, std::string("<vector<std::size_t>>"), defaulted);
|
||||
|
||||
if (typeIs<std::uint32_t>(varValue))
|
||||
return T::template Value<std::uint32_t>(varValue, std::string("<std::uint32_t>"), defaulted, empty);
|
||||
if (typeid(std::uint32_t) == varVal.value().type())
|
||||
return T::template Value<std::uint32_t>(varVal, std::string("<std::uint32_t>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<std::uint32_t>>(varValue))
|
||||
return T::template Value<std::vector<std::uint32_t>>(varValue, std::string("<vector<std::uint32_t>>"), defaulted, empty);
|
||||
if (typeid(std::vector<std::uint32_t>) == varVal.value().type())
|
||||
return T::template Value<std::vector<std::uint32_t>>(varVal, std::string("<vector<std::uint32_t>>"), defaulted);
|
||||
|
||||
if (typeIs<std::uint64_t>(varValue))
|
||||
return T::template Value<std::uint64_t>(varValue, std::string("<std::uint64_t>"), defaulted, empty);
|
||||
if (typeid(std::uint64_t) == varVal.value().type())
|
||||
return T::template Value<std::uint64_t>(varVal, std::string("<std::uint64_t>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<std::uint64_t>>(varValue))
|
||||
return T::template Value<std::vector<std::uint64_t>>(varValue, std::string("<vector<std::uint64_t>>"), defaulted, empty);
|
||||
if (typeid(std::vector<std::uint64_t>) == varVal.value().type())
|
||||
return T::template Value<std::vector<std::uint64_t>>(varVal, std::string("<vector<std::uint64_t>>"), defaulted);
|
||||
|
||||
if (typeIs<bool>(varValue))
|
||||
return T::template Value<bool>(varValue, std::string("<bool>"), defaulted, empty);
|
||||
if (typeid(bool) == varVal.value().type())
|
||||
return T::template Value<bool>(varVal, std::string("<bool>"), defaulted);
|
||||
|
||||
if (typeIs<std::vector<bool>>(varValue))
|
||||
return T::template Value<std::vector<bool>>(varValue, std::string("<vector<bool>>"), defaulted, empty);
|
||||
if (typeid(std::vector<bool>) == varVal.value().type())
|
||||
return T::template Value<std::vector<bool>>(varVal, std::string("<vector<bool>>"), defaulted);
|
||||
|
||||
if (typeIs<boost::filesystem::path>(varValue))
|
||||
return T::template Value<boost::filesystem::path>(varValue, std::string("<boost::filesystem::path>"), defaulted, empty);
|
||||
if (typeid(boost::filesystem::path) == varVal.value().type())
|
||||
return T::template Value<boost::filesystem::path>(varVal, std::string("<boost::filesystem::path>"), defaulted);
|
||||
|
||||
if (typeid(std::vector<boost::filesystem::path>) == varVal.value().type())
|
||||
return T::template Value<std::vector<boost::filesystem::path>>(varVal, std::string("<std::vector<boost::filesystem::path>>"), defaulted);
|
||||
|
||||
// if we get here, the type is not supported return unknown info
|
||||
return T::DefaultValue(defaulted, empty);
|
||||
return T::DefaultValue(defaulted);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,98 +0,0 @@
|
||||
################################################################################
|
||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
# Create a library called "ProgOptionTest"
|
||||
|
||||
# Test fair-prog-opt
|
||||
|
||||
# scripts
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testMQOptions1.sh.in ${CMAKE_BINARY_DIR}/bin/testMQOptions1.sh )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testMQOptions2.sh.in ${CMAKE_BINARY_DIR}/bin/testMQOptions2.sh )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testMQOptions3.sh.in ${CMAKE_BINARY_DIR}/bin/testMQOptions3.sh )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testMQOptions4.sh.in ${CMAKE_BINARY_DIR}/bin/testMQOptions4.sh )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testMQOptions5.sh.in ${CMAKE_BINARY_DIR}/bin/testMQOptions5.sh )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/start-bsampler-sink.sh.in ${CMAKE_BINARY_DIR}/bin/start-bsampler-sink.sh )
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${CMAKE_BINARY_DIR}/bin/testMQOptions1.sh")
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${CMAKE_BINARY_DIR}/bin/testMQOptions2.sh")
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${CMAKE_BINARY_DIR}/bin/testMQOptions3.sh")
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${CMAKE_BINARY_DIR}/bin/testMQOptions4.sh")
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${CMAKE_BINARY_DIR}/bin/testMQOptions5.sh")
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${CMAKE_BINARY_DIR}/bin/start-bsampler-sink.sh")
|
||||
|
||||
# Config/xml/json example file
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/ConfigFileTest.cfg.in ${CMAKE_BINARY_DIR}/bin/ConfigFileTest.cfg)
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testXML.xml ${CMAKE_BINARY_DIR}/bin/testXML.xml )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/testJSON.json ${CMAKE_BINARY_DIR}/bin/testJSON.json )
|
||||
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/macro/bsampler-sink.json ${CMAKE_BINARY_DIR}/bin/bsampler-sink.json )
|
||||
|
||||
|
||||
|
||||
set(INCLUDE_DIRECTORIES
|
||||
${CMAKE_SOURCE_DIR}/fairmq
|
||||
${CMAKE_SOURCE_DIR}/fairmq/options
|
||||
${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/lib
|
||||
${CMAKE_SOURCE_DIR}/fairmq/options/ProgOptionTest/run
|
||||
)
|
||||
|
||||
Set(SYSTEM_INCLUDE_DIRECTORIES
|
||||
${SYSTEM_INCLUDE_DIRECTORIES}
|
||||
)
|
||||
|
||||
include_directories(${INCLUDE_DIRECTORIES})
|
||||
include_directories(${SYSTEM_INCLUDE_DIRECTORIES})
|
||||
|
||||
set(LINK_DIRECTORIES
|
||||
${Boost_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
link_directories(${LINK_DIRECTORIES})
|
||||
|
||||
Set(SRCS
|
||||
lib/FairMQParserExample.cxx
|
||||
)
|
||||
|
||||
Set(LIBRARY_NAME ProgOptionTest)
|
||||
|
||||
If (Boost_FOUND)
|
||||
Set(DEPENDENCIES
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||
FairMQ
|
||||
)
|
||||
EndIf (Boost_FOUND)
|
||||
|
||||
GENERATE_LIBRARY()
|
||||
|
||||
|
||||
If (Boost_FOUND)
|
||||
Set(Exe_Names
|
||||
runtestMQOption1
|
||||
runtestMQOption2
|
||||
runOptTestSampler
|
||||
runOptTestSink
|
||||
)
|
||||
|
||||
|
||||
set(Exe_Source
|
||||
run/testMQoptions1.cxx
|
||||
run/testMQoptions2.cxx
|
||||
run/runOptTestSampler.cxx
|
||||
run/runOptTestSink.cxx
|
||||
)
|
||||
|
||||
List(LENGTH Exe_Names _length)
|
||||
Math(EXPR _length ${_length}-1)
|
||||
|
||||
ForEach(_file RANGE 0 ${_length})
|
||||
List(GET Exe_Names ${_file} _name)
|
||||
List(GET Exe_Source ${_file} _src)
|
||||
Set(EXE_NAME ${_name})
|
||||
Set(SRCS ${_src})
|
||||
Set(DEPENDENCIES ProgOptionTest)
|
||||
GENERATE_EXECUTABLE()
|
||||
EndForEach(_file RANGE 0 ${_length})
|
||||
EndIf (Boost_FOUND)
|
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* File: FairMQParserExample.cxx
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on May 14, 2015, 5:01 PM
|
||||
*/
|
||||
|
||||
#include "FairMQParserExample.h"
|
||||
#include "FairMQLogger.h"
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
|
||||
|
||||
namespace FairMQParser
|
||||
{
|
||||
|
||||
// other xml examples
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
boost::property_tree::ptree MQXML2::UserParser(const std::string& filename)
|
||||
{
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_xml(filename, pt);
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO : finish implementation
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
boost::property_tree::ptree MQXML3::UserParser(const std::string& filename, const std::string& devicename)
|
||||
{
|
||||
// Create an empty property tree object
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_xml(filename, pt);
|
||||
|
||||
|
||||
// Create fair mq map
|
||||
|
||||
auto xml = pt.get_child("");
|
||||
std::vector<std::pair<std::string, boost::property_tree::ptree>> match;
|
||||
std::pair<std::string, boost::property_tree::ptree> device_match;
|
||||
|
||||
ProcessTree(xml.begin (), xml.end (), std::back_inserter(match),
|
||||
[] (const std::string& key) { return key == "device"; });
|
||||
|
||||
|
||||
// for each device
|
||||
for (const auto& pair: match)
|
||||
{
|
||||
if(pair.second.get<std::string>("<xmlattr>.name") == devicename)
|
||||
{
|
||||
device_match=pair;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//match.erase(std::remove(match.begin(), match.end(), pair), match.end());
|
||||
continue;
|
||||
}
|
||||
|
||||
//std::cout << "pair.first " << pair.first << std::endl;//device
|
||||
//std::cout << "\t node = " << pair.first
|
||||
// << "\t name = " << pair.second.get<std::string>("<xmlattr>.name")
|
||||
// << "\t id = " << pair.second.get<std::string>("<xmlattr>.id");
|
||||
//std::cout<<std::endl;
|
||||
}
|
||||
|
||||
return device_match.second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // end FairMQParser namespace
|
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* File: FairMQParserExample.h
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on May 14, 2015, 5:01 PM
|
||||
*/
|
||||
|
||||
#ifndef FAIRMQPARSEREXAMPLE_H
|
||||
#define FAIRMQPARSEREXAMPLE_H
|
||||
|
||||
// FairRoot
|
||||
#include "FairMQChannel.h"
|
||||
#include "FairMQParser.h"
|
||||
|
||||
// Boost
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
// std
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace FairMQParser
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////// XML ////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// xml example 2
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
struct MQXML2
|
||||
{
|
||||
boost::property_tree::ptree UserParser(const std::string& filename);
|
||||
};
|
||||
|
||||
// xml example 3
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
struct MQXML3
|
||||
{
|
||||
boost::property_tree::ptree UserParser(const std::string& filename, const std::string& root_node);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// template function iterating over the whole boost property tree
|
||||
template <typename Input_tree_It, typename Output_tree_It, typename Compare_key>
|
||||
void ProcessTree(Input_tree_It first, Input_tree_It last, Output_tree_It dest, Compare_key compare)
|
||||
{
|
||||
//typedef typename std::iterator_traits<Input_tree_It>::reference reference;
|
||||
|
||||
if (first == last)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto begin = first->second.begin ();
|
||||
auto end = first->second.end ();
|
||||
|
||||
if (begin != end)
|
||||
{
|
||||
ProcessTree (begin, end, dest, compare);
|
||||
}
|
||||
|
||||
if (compare (first->first))
|
||||
{
|
||||
dest = *first;
|
||||
}
|
||||
|
||||
ProcessTree (++first, last, dest, compare);
|
||||
}
|
||||
|
||||
class no_id_exception: public std::exception
|
||||
{
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return "Empty string for the device-id in FairMQParser::ptreeToMQMap(...) function";
|
||||
}
|
||||
};
|
||||
|
||||
} // end FairMQParser namespace
|
||||
#endif /* FAIRMQPARSEREXAMPLE_H */
|
||||
|
@@ -1,38 +0,0 @@
|
||||
#----------------------------------------------------
|
||||
# comments :
|
||||
# brackets [] are used to group options. For example :
|
||||
#
|
||||
# [xml.config]
|
||||
# node.root = fairMQOptions
|
||||
#
|
||||
# is equivalent to
|
||||
# xml.config.node.root = fairMQOptions
|
||||
#----------------------------------------------------
|
||||
|
||||
config-json-file = @CMAKE_BINARY_DIR@/bin/testJSON.json
|
||||
config-xml-file = @CMAKE_BINARY_DIR@/bin/testXML.xml
|
||||
|
||||
#
|
||||
device-id = merger
|
||||
|
||||
#-------------------
|
||||
[xml.config]
|
||||
|
||||
#filename = @CMAKE_BINARY_DIR@/bin/testXML.xml
|
||||
node.root = fairMQOptions
|
||||
|
||||
|
||||
#-------------------
|
||||
[input.file]
|
||||
|
||||
name = sampler_file_name.root
|
||||
tree = sampler_tree
|
||||
branch = sampler_branch
|
||||
|
||||
|
||||
#-------------------
|
||||
[output.file]
|
||||
|
||||
name = sink_filename.root
|
||||
tree = sink_tree
|
||||
branch = sink_branch
|
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
JSONFILE="@CMAKE_BINARY_DIR@/bin/bsampler-sink.json"
|
||||
|
||||
# Note: device-id value must correspond to the device id given in the json file
|
||||
|
||||
BSAMPLER="runOptTestSampler"
|
||||
BSAMPLER+=" --config-json-file $JSONFILE"
|
||||
BSAMPLER+=" --id bsampler1"
|
||||
|
||||
xterm -geometry 150x23+0+0 -hold -e @CMAKE_BINARY_DIR@/bin/$BSAMPLER &
|
||||
|
||||
|
||||
SINK="runOptTestSink"
|
||||
SINK+=" --config-json-file $JSONFILE"
|
||||
SINK+=" --id sink1"
|
||||
|
||||
xterm -geometry 150x23+0+350 -hold -e @CMAKE_BINARY_DIR@/bin/$SINK &
|
@@ -1,63 +0,0 @@
|
||||
{
|
||||
"fairMQOptions": {
|
||||
"devices": [
|
||||
{
|
||||
"id": "merger1",
|
||||
"channels": [
|
||||
{
|
||||
"name": "two_inputs_channel",
|
||||
"sockets": [
|
||||
{
|
||||
"type": "pull",
|
||||
"method": "",
|
||||
"address": "tcp://*:5569",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"rateLogging": 1
|
||||
},
|
||||
{
|
||||
"type": "pull",
|
||||
"method": "bind",
|
||||
"address": "tcp://*:5570",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"rateLogging": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "one_output_channel",
|
||||
"sockets": [
|
||||
{
|
||||
"type": "push",
|
||||
"method": "connect",
|
||||
"address": "tcp://*:5571",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"rateLogging": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "sink1",
|
||||
"channels": [
|
||||
{
|
||||
"name": "one_input",
|
||||
"sockets": [
|
||||
{
|
||||
"type": "pull",
|
||||
"method": "bind",
|
||||
"address": "tcp://localhost:5571",
|
||||
"sndBufSize": 1000,
|
||||
"rcvBufSize": 1000,
|
||||
"rateLogging": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUN_TEST="runtestMQOption1"
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
RUN_TEST+=" $*"
|
||||
fi
|
||||
|
||||
RUN_TEST+=" --config-xml-file @CMAKE_BINARY_DIR@/bin/testXML.xml"
|
||||
|
||||
@CMAKE_BINARY_DIR@/bin/$RUN_TEST
|
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUN_TEST="runtestMQOption1"
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
RUN_TEST+=" $*"
|
||||
fi
|
||||
|
||||
XML_CMD_LINE="<fairMQOptions>"
|
||||
XML_CMD_LINE+="<device name=\"merger\" id=\"1234\" >"
|
||||
XML_CMD_LINE+=" <channel name=\"two_inputs_channel\" >"
|
||||
XML_CMD_LINE+=" <socket name=\"input1\" >"
|
||||
XML_CMD_LINE+=" <type>pull</type>"
|
||||
XML_CMD_LINE+=" <method>bind</method>"
|
||||
XML_CMD_LINE+=" <address>tcp://*:5569</address>"
|
||||
XML_CMD_LINE+=" <sndBufSize>1000</sndBufSize>"
|
||||
XML_CMD_LINE+=" <rcvBufSize>1000</rcvBufSize>"
|
||||
XML_CMD_LINE+=" <rateLogging>1</rateLogging>"
|
||||
XML_CMD_LINE+=" </socket>"
|
||||
XML_CMD_LINE+=" <socket name=\"input2\" >"
|
||||
XML_CMD_LINE+=" <type>pull</type>"
|
||||
XML_CMD_LINE+=" <method>bind</method>"
|
||||
XML_CMD_LINE+=" <address>tcp://*:5570</address>"
|
||||
XML_CMD_LINE+=" <sndBufSize>1000</sndBufSize>"
|
||||
XML_CMD_LINE+=" <rcvBufSize>1000</rcvBufSize>"
|
||||
XML_CMD_LINE+=" <rateLogging>1</rateLogging>"
|
||||
XML_CMD_LINE+=" </socket>"
|
||||
XML_CMD_LINE+=" </channel>"
|
||||
XML_CMD_LINE+=" <channel name=\"one_output_channel\" >"
|
||||
XML_CMD_LINE+=" <socket name=\"output1\" >"
|
||||
XML_CMD_LINE+=" <type>push</type>"
|
||||
XML_CMD_LINE+=" <method>connect</method>"
|
||||
XML_CMD_LINE+=" <address>tcp://*:5571</address>"
|
||||
XML_CMD_LINE+=" <sndBufSize>1000</sndBufSize>"
|
||||
XML_CMD_LINE+=" <rcvBufSize>1000</rcvBufSize>"
|
||||
XML_CMD_LINE+=" <rateLogging>1</rateLogging>"
|
||||
XML_CMD_LINE+=" </socket>"
|
||||
XML_CMD_LINE+=" </channel>"
|
||||
XML_CMD_LINE+=" </device>"
|
||||
XML_CMD_LINE+=" <device name=\"sink\" id=\"4567\" >"
|
||||
XML_CMD_LINE+=" <channel name=\"one_input\" >"
|
||||
XML_CMD_LINE+=" <socket name=\"input1\" >"
|
||||
XML_CMD_LINE+=" <type>pull</type>"
|
||||
XML_CMD_LINE+=" <method>bind</method>"
|
||||
XML_CMD_LINE+=" <address>tcp://localhost:5571</address>"
|
||||
XML_CMD_LINE+=" <sndBufSize>1000</sndBufSize>"
|
||||
XML_CMD_LINE+=" <rcvBufSize>1000</rcvBufSize>"
|
||||
XML_CMD_LINE+=" <rateLogging>1</rateLogging>"
|
||||
XML_CMD_LINE+=" </socket>"
|
||||
XML_CMD_LINE+=" </channel>"
|
||||
XML_CMD_LINE+=" </device>"
|
||||
XML_CMD_LINE+="</fairmq_option>"
|
||||
|
||||
|
||||
|
||||
RUN_TEST+=" --config-xml-string $XML_CMD_LINE"
|
||||
|
||||
|
||||
@CMAKE_BINARY_DIR@/bin/$RUN_TEST
|
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUN_TEST="runtestMQOption2"
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
RUN_TEST+=" $*"
|
||||
fi
|
||||
RUN_TEST+=" --config @CMAKE_BINARY_DIR@/bin/ConfigFileTest.cfg"
|
||||
|
||||
@CMAKE_BINARY_DIR@/bin/$RUN_TEST
|
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUN_TEST="runtestMQOption1"
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
RUN_TEST+=" $*"
|
||||
fi
|
||||
|
||||
RUN_TEST+=" --config-json-file @CMAKE_BINARY_DIR@/bin/testJSON.json"
|
||||
|
||||
@CMAKE_BINARY_DIR@/bin/$RUN_TEST
|
@@ -1,77 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUN_TEST="runtestMQOption1"
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
RUN_TEST+=" $*"
|
||||
fi
|
||||
|
||||
JSON_CMD_LINE="{"
|
||||
JSON_CMD_LINE+=" \"fairMQOptions\": {"
|
||||
JSON_CMD_LINE+=" \"device\": "
|
||||
JSON_CMD_LINE+=" {"
|
||||
JSON_CMD_LINE+=" \"name\": \"merger\","
|
||||
JSON_CMD_LINE+=" \"id\": \"1234\","
|
||||
JSON_CMD_LINE+=" \"channel\": "
|
||||
JSON_CMD_LINE+=" {"
|
||||
JSON_CMD_LINE+=" \"name\": \"two_inputs_channel\","
|
||||
JSON_CMD_LINE+=" \"socket\": "
|
||||
JSON_CMD_LINE+=" {"
|
||||
JSON_CMD_LINE+=" \"name\": \"input1\","
|
||||
JSON_CMD_LINE+=" \"type\": \"pull\","
|
||||
JSON_CMD_LINE+=" \"method\": \"bind\","
|
||||
JSON_CMD_LINE+=" \"address\": \"tcp://*:5569\","
|
||||
JSON_CMD_LINE+=" \"sndBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rcvBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rateLogging\": \"1\" "
|
||||
JSON_CMD_LINE+=" },"
|
||||
JSON_CMD_LINE+=" \"socket\": "
|
||||
JSON_CMD_LINE+=" {"
|
||||
JSON_CMD_LINE+=" \"name\": \"input2\","
|
||||
JSON_CMD_LINE+=" \"type\": \"pull\","
|
||||
JSON_CMD_LINE+=" \"method\": \"bind\","
|
||||
JSON_CMD_LINE+=" \"address\": \"tcp://*:5570\","
|
||||
JSON_CMD_LINE+=" \"sndBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rcvBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rateLogging\": \"1\" "
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+=" },"
|
||||
JSON_CMD_LINE+=" \"channel\":"
|
||||
JSON_CMD_LINE+=" {"
|
||||
JSON_CMD_LINE+=" \"name\": \"one_output_channel\","
|
||||
JSON_CMD_LINE+=" \"socket\": {"
|
||||
JSON_CMD_LINE+=" \"name\": \"output1\","
|
||||
JSON_CMD_LINE+=" \"type\": \"push\","
|
||||
JSON_CMD_LINE+=" \"method\": \"connect\","
|
||||
JSON_CMD_LINE+=" \"address\": \"tcp://*:5571\","
|
||||
JSON_CMD_LINE+=" \"sndBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rcvBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rateLogging\": \"1\" "
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+=" },"
|
||||
JSON_CMD_LINE+=" \"device\":"
|
||||
JSON_CMD_LINE+=" {"
|
||||
JSON_CMD_LINE+=" \"name\": \"sink\","
|
||||
JSON_CMD_LINE+=" \"id\": \"4567\","
|
||||
JSON_CMD_LINE+=" \"channel\": {"
|
||||
JSON_CMD_LINE+=" \"name\": \"one_input\","
|
||||
JSON_CMD_LINE+=" \"socket\": {"
|
||||
JSON_CMD_LINE+=" \"name\": \"input1\","
|
||||
JSON_CMD_LINE+=" \"type\": \"pull\","
|
||||
JSON_CMD_LINE+=" \"method\": \"bind\","
|
||||
JSON_CMD_LINE+=" \"address\": \"tcp://localhost:5571\","
|
||||
JSON_CMD_LINE+=" \"sndBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rcvBufSize\": \"1000\","
|
||||
JSON_CMD_LINE+=" \"rateLogging\": \"1\" "
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+=" }"
|
||||
JSON_CMD_LINE+="}"
|
||||
|
||||
|
||||
RUN_TEST+=" --config-json-string $JSON_CMD_LINE"
|
||||
|
||||
|
||||
@CMAKE_BINARY_DIR@/bin/$RUN_TEST
|
@@ -1,44 +0,0 @@
|
||||
<fairMQOptions>
|
||||
<device name="merger" id="merger">
|
||||
<channel name="two_inputs_channel">
|
||||
<socket name="input1">
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://*:5569</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
<socket name="input2">
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://*:5570</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
<channel name="one_output_channel">
|
||||
<socket name="output1">
|
||||
<type>push</type>
|
||||
<method>connect</method>
|
||||
<address>tcp://*:5571</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
</device>
|
||||
<device name="sink" id="sink">
|
||||
<channel name="one_input">
|
||||
<socket name="input1">
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://localhost:5571</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
</device>
|
||||
</fairMQOptions>
|
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* File: runOptTestSampler.cxx
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on June 10, 2015, 3:34 PM
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
/// std
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/// boost
|
||||
#include "boost/program_options.hpp"
|
||||
|
||||
/// FairRoot/FairMQ
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/// main
|
||||
//////////////////////////////////////////////////////////////
|
||||
using namespace std;
|
||||
using namespace FairMQParser;
|
||||
using namespace boost::program_options;
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FairMQProgOptions config;
|
||||
try
|
||||
{
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// define key specific to the BenchmarkSampler in options_description
|
||||
|
||||
int eventSize;
|
||||
int eventRate;
|
||||
int ioThreads;
|
||||
options_description sampler_options("Sampler options");
|
||||
sampler_options.add_options()
|
||||
("event-size", value<int>(&eventSize)->default_value(1000), "Event size in bytes")
|
||||
("event-rate", value<int>(&eventRate)->default_value(0), "Event rate limit in maximum number of events per second")
|
||||
("io-threads", value<int>(&ioThreads)->default_value(1), "Number of I/O threads");
|
||||
|
||||
// and add it to cmdline option of FairMQProgOptions
|
||||
config.AddToCmdLineOptions(sampler_options);
|
||||
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// enable simple config txt/INI file
|
||||
//config.EnableCfgFile();
|
||||
//config.AddToCfgFileOptions(sampler_options,false);
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// Parse command line options and store in variable map
|
||||
if(config.ParseAll(argc,argv,true))
|
||||
return 0;
|
||||
|
||||
// keys defined in FairMQProgOptions
|
||||
string filename=config.GetValue<string>("config-json-file");
|
||||
string deviceID=config.GetValue<string>("id");
|
||||
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// User defined parsing method.
|
||||
|
||||
config.UserParser<JSON>(filename,deviceID);
|
||||
FairMQMap channels=config.GetFairMQMap();
|
||||
//set device here
|
||||
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << e.what();
|
||||
LOG(info) << "Command line options are the following : ";
|
||||
config.PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* File: runOptTestSink.cxx
|
||||
* Author: winckler
|
||||
*
|
||||
* Created on June 10, 2015, 3:34 PM
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
/// std
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/// boost
|
||||
#include "boost/program_options.hpp"
|
||||
|
||||
/// FairRoot/FairMQ
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/// main
|
||||
//////////////////////////////////////////////////////////////
|
||||
using namespace std;
|
||||
using namespace FairMQParser;
|
||||
using namespace boost::program_options;
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FairMQProgOptions config;
|
||||
try
|
||||
{
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// define key specific to the BenchmarkSampler in options_description
|
||||
|
||||
int eventSize;
|
||||
int eventRate;
|
||||
int ioThreads;
|
||||
options_description Sink_options("Sink options");
|
||||
Sink_options.add_options()
|
||||
("io-threads", value<int>(&ioThreads)->default_value(1), "Number of I/O threads");
|
||||
|
||||
// and add it to cmdline option of FairMQProgOptions
|
||||
config.AddToCmdLineOptions(Sink_options);
|
||||
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// Parse command line options and store in variable map
|
||||
if(config.ParseAll(argc,argv,true))
|
||||
return 0;
|
||||
|
||||
// keys defined in FairMQProgOptions
|
||||
string filename=config.GetValue<string>("config-json-file");
|
||||
string deviceID=config.GetValue<string>("id");
|
||||
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// User defined parsing method.
|
||||
|
||||
config.UserParser<JSON>(filename,deviceID);
|
||||
FairMQMap channels=config.GetFairMQMap();
|
||||
//set device here
|
||||
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << e.what();
|
||||
LOG(info) << "Command line options are the following : ";
|
||||
config.PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,141 +0,0 @@
|
||||
/// std
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/// boost
|
||||
#include "boost/program_options.hpp"
|
||||
|
||||
/// FairRoot/FairMQ
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
|
||||
// Parse xml from file
|
||||
int testXML1(FairMQProgOptions* config)
|
||||
{
|
||||
LOG(info)<<"--------- test XML1 ---------\n";
|
||||
std::string filename;
|
||||
std::string XMLrootNode;
|
||||
|
||||
filename=config->GetValue<std::string>("config-xml-file");
|
||||
XMLrootNode=config->GetValue<std::string>("xml.config.node.root");
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
config->UserParser<FairMQParser::XML>(filename,id,XMLrootNode);
|
||||
// other xml parser test
|
||||
config->UserParser<FairMQParser::MQXML2>(filename);
|
||||
config->UserParser<FairMQParser::MQXML3>(filename,"merger");
|
||||
|
||||
LOG(info)<<"--------- test XML1 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse xml from command line
|
||||
int testXML2(FairMQProgOptions* config)
|
||||
{
|
||||
LOG(info)<<"--------- test XML2 ---------\n";
|
||||
std::string XML;
|
||||
std::string XMLrootNode;
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
XMLrootNode=config->GetValue<std::string>("xml.config.node.root");
|
||||
|
||||
// Note: convert the vector<string> into one string with GetStringValue(key)
|
||||
XML=config->GetStringValue("config-xml-string");
|
||||
|
||||
std::stringstream iss;
|
||||
iss << XML;
|
||||
config->UserParser<FairMQParser::XML>(iss,id,XMLrootNode);
|
||||
|
||||
LOG(info)<<"--------- test XML2 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse json from file
|
||||
int testJSON1(FairMQProgOptions* config)
|
||||
{
|
||||
LOG(info)<<"--------- test JSON1 ---------\n";
|
||||
std::string filename;
|
||||
std::string JSONrootNode;
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
|
||||
filename=config->GetValue<std::string>("config-json-file");
|
||||
JSONrootNode=config->GetValue<std::string>("json.config.node.root");
|
||||
|
||||
config->UserParser<FairMQParser::JSON>(filename,id,JSONrootNode);
|
||||
|
||||
LOG(info)<<"--------- test JSON1 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse json from command line
|
||||
int testJSON2(FairMQProgOptions* config)
|
||||
{
|
||||
LOG(info)<<"--------- test JSON2 ---------\n";
|
||||
std::string JSON;
|
||||
std::string JSONrootNode;
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
JSONrootNode=config->GetValue<std::string>("json.config.node.root");
|
||||
|
||||
// Note: convert the vector<string> into one string with GetStringValue(key)
|
||||
JSON=config->GetStringValue("config-json-string");
|
||||
|
||||
std::stringstream iss;
|
||||
iss << JSON;
|
||||
config->UserParser<FairMQParser::JSON>(iss,id,JSONrootNode);
|
||||
|
||||
LOG(info)<<"--------- test JSON2 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FairMQProgOptions* config= new FairMQProgOptions();
|
||||
try
|
||||
{
|
||||
po::options_description format_desc("XML or JSON input");
|
||||
format_desc.add_options()
|
||||
("xml.config.node.root", po::value<std::string>()->default_value("fairMQOptions"), "xml root node ")
|
||||
("json.config.node.root", po::value<std::string>()->default_value("fairMQOptions"), "json root node ")
|
||||
;
|
||||
|
||||
config->AddToCmdLineOptions(format_desc);
|
||||
|
||||
// Parse command line
|
||||
if (config->ParseAll(argc,argv))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set severity level (Default is 0=DEBUG)
|
||||
int severity = config->GetValue<int>("severity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(severity);
|
||||
SET_LOGGER_LEVEL(lvl);
|
||||
|
||||
// Parse xml or json from cmd line or file
|
||||
if (config->GetVarMap().count("config-xml-file"))
|
||||
{
|
||||
testXML1(config);
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-xml-string"))
|
||||
{
|
||||
testXML2(config);
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-json-file"))
|
||||
{
|
||||
testJSON1(config);
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-json-string"))
|
||||
{
|
||||
testJSON2(config);
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(error) << e.what();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
/// std
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
/// boost
|
||||
#include "boost/program_options.hpp"
|
||||
|
||||
/// FairRoot/FairMQ
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/// main
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
FairMQProgOptions config;
|
||||
|
||||
po::options_description format_desc("XML input");
|
||||
format_desc.add_options()
|
||||
("xml.config.node.root", po::value<std::string>()->default_value("fairMQOptions"), "xml root node ")
|
||||
;
|
||||
|
||||
po::options_description io_file_opt_desc("I/O file Options");
|
||||
io_file_opt_desc.add_options()
|
||||
("input.file.name", po::value<std::string>(), "input file name")
|
||||
("input.file.tree", po::value<std::string>(), "input tree name")
|
||||
("input.file.branch", po::value<std::string>(), "input branch name")
|
||||
("output.file.name", po::value<std::string>(), "output file name")
|
||||
("output.file.tree", po::value<std::string>(), "output tree name")
|
||||
("output.file.branch", po::value<std::string>(), "output branch name")
|
||||
;
|
||||
|
||||
config.AddToCmdLineOptions(format_desc);
|
||||
config.AddToCmdLineOptions(io_file_opt_desc);
|
||||
|
||||
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
||||
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
||||
config.AddToCfgFileOptions(io_file_opt_desc,false);
|
||||
|
||||
// Parse command line and config file
|
||||
if(config.ParseAll(argc,argv))
|
||||
return 0;
|
||||
|
||||
// Set severity level (Default is 0=DEBUG)
|
||||
int severity = config.GetValue<int>("severity");
|
||||
FairMQLogger::Level lvl = static_cast<FairMQLogger::Level>(severity);
|
||||
SET_LOGGER_LEVEL(lvl);
|
||||
|
||||
// parse XML file
|
||||
std::string filename;
|
||||
std::string XMLrootNode;
|
||||
|
||||
filename=config.GetValue<std::string>("config-xml-file");
|
||||
XMLrootNode=config.GetValue<std::string>("xml.config.node.root");
|
||||
std::string id=config.GetValue<std::string>("id");
|
||||
config.UserParser<FairMQParser::XML>(filename,id,XMLrootNode);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(error) << e.what();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -63,21 +63,18 @@ int main(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
// create option manager object
|
||||
FairMQProgOptions config;
|
||||
|
||||
// add key description to cmd line options
|
||||
config.GetCmdLineOptions().add_options()
|
||||
("data-rate", po::value<double>()->default_value(0.5), "Data rate");
|
||||
("data-rate", boost::program_options::value<double>()->default_value(0.5), "Data rate");
|
||||
|
||||
// parse command lines, parse json file and init FairMQMap
|
||||
config.ParseAll(argc, argv, true);
|
||||
|
||||
// // get FairMQMap
|
||||
// auto map1 = config.GetFairMQMap();
|
||||
|
||||
// // update value in variable map, and propagate the update to the FairMQMap
|
||||
// config.UpdateValue<string>("chans.data.0.address","tcp://localhost:1234");
|
||||
// config.SetValue<string>("chans.data.0.address","tcp://localhost:1234");
|
||||
|
||||
// // get the updated FairMQMap
|
||||
// auto map2 = config.GetFairMQMap();
|
||||
@@ -89,7 +86,6 @@ int main(int argc, char** argv)
|
||||
// config.UpdateChannelMap(map2);
|
||||
|
||||
MyDevice device;
|
||||
// device.CatchSignals();
|
||||
device.SetConfig(config);
|
||||
|
||||
// getting as string and conversion helpers
|
||||
@@ -130,45 +126,30 @@ int main(int argc, char** argv)
|
||||
|
||||
LOG(info) << "Starting value updates...\n";
|
||||
|
||||
config.UpdateValue<string>("chans.data.0.address", "tcp://localhost:4321");
|
||||
config.SetValue<string>("chans.data.0.address", "tcp://localhost:4321");
|
||||
LOG(info) << "config: " << config.GetValue<string>("chans.data.0.address");
|
||||
LOG(info) << "device: " << device.fChannels.at("data").at(0).GetAddress() << endl;
|
||||
|
||||
config.UpdateValue<int>("chans.data.0.rcvBufSize", 100);
|
||||
config.SetValue<int>("chans.data.0.rcvBufSize", 100);
|
||||
LOG(info) << "config: " << config.GetValue<int>("chans.data.0.rcvBufSize");
|
||||
LOG(info) << "device: " << device.fChannels.at("data").at(0).GetRcvBufSize() << endl;
|
||||
|
||||
config.UpdateValue<double>("data-rate", 0.9);
|
||||
config.SetValue<double>("data-rate", 0.9);
|
||||
LOG(info) << "config: " << config.GetValue<double>("data-rate");
|
||||
LOG(info) << "device: " << device.GetRate() << endl;
|
||||
// device.Print();
|
||||
device.Print();
|
||||
|
||||
LOG(info) << "nase: " << config.GetValue<double>("nase");
|
||||
|
||||
config.Unsubscribe<string>("test");
|
||||
config.Unsubscribe<int>("test");
|
||||
config.Unsubscribe<double>("test");
|
||||
// advanced commands
|
||||
|
||||
// LOG(info) << "-------------------- start custom 1";
|
||||
|
||||
// config.Connect<EventId::Custom, MyDevice&, double>("myNewKey", [](MyDevice& d, double val)
|
||||
// {
|
||||
// d.SetRate(val);
|
||||
// d.Print();
|
||||
// });
|
||||
|
||||
// config.Emit<EventId::Custom, MyDevice&, double>("myNewKey", device, 0.123);
|
||||
|
||||
// LOG(info) << "-------------------- start custom 2 with function";
|
||||
// config.Connect<EventId::Custom, MyDevice&, double>("function example", &MyCallBack);
|
||||
|
||||
// config.Emit<EventId::Custom, MyDevice&, double>("function example", device, 6.66);
|
||||
device.ChangeState("END");
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
LOG(error) << "Unhandled Exception reached the top of main: "
|
||||
<< e.what() << ", application will now exit";
|
||||
LOG(error) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@@ -1,11 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
TRANSPORT="zeromq"
|
||||
VERBOSE="DEBUG"
|
||||
|
||||
JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json"
|
||||
|
||||
########################## start DEVICE
|
||||
DEVICE="runConfigExample --transport $TRANSPORT --severity $VERBOSE"
|
||||
DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE"
|
||||
@CMAKE_BINARY_DIR@/bin/$DEVICE
|
||||
DEVICE="runConfigExample"
|
||||
DEVICE+=" --id sampler1 --channel-config name=data,type=push,method=bind,address=tcp://*:5555,rateLogging=0"
|
||||
@CMAKE_CURRENT_BINARY_DIR@/$DEVICE
|
||||
|
@@ -107,6 +107,7 @@ auto Control::InteractiveMode() -> void
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure
|
||||
t.c_lflag &= ~ICANON; // disable canonical input
|
||||
t.c_lflag &= ~ECHO; // do not echo input chars
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings
|
||||
|
||||
PrintInteractiveHelp();
|
||||
@@ -154,6 +155,22 @@ auto Control::InteractiveMode() -> void
|
||||
LOG(info) << "\n\n --> [d] reset device\n";
|
||||
ChangeDeviceState(DeviceStateTransition::ResetDevice);
|
||||
break;
|
||||
case 'k':
|
||||
LOG(info) << "\n\n --> [k] increase log severity\n";
|
||||
CycleLogConsoleSeverityUp();
|
||||
break;
|
||||
case 'l':
|
||||
LOG(info) << "\n\n --> [l] decrease log severity\n";
|
||||
CycleLogConsoleSeverityDown();
|
||||
break;
|
||||
case 'n':
|
||||
LOG(info) << "\n\n --> [n] increase log verbosity\n";
|
||||
CycleLogVerbosityUp();
|
||||
break;
|
||||
case 'm':
|
||||
LOG(info) << "\n\n --> [m] decrease log verbosity\n";
|
||||
CycleLogVerbosityDown();
|
||||
break;
|
||||
case 'h':
|
||||
LOG(info) << "\n\n --> [h] help\n";
|
||||
PrintInteractiveHelp();
|
||||
@@ -181,6 +198,7 @@ auto Control::InteractiveMode() -> void
|
||||
|
||||
tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure
|
||||
t.c_lflag |= ICANON; // re-enable canonical input
|
||||
t.c_lflag |= ECHO; // echo input chars
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings
|
||||
|
||||
if (!fDeviceTerminationRequested)
|
||||
@@ -197,8 +215,11 @@ auto Control::InteractiveMode() -> void
|
||||
|
||||
auto Control::PrintInteractiveHelp() -> void
|
||||
{
|
||||
LOG(info) << "Use keys to control the state machine:\n\n"
|
||||
<< "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device\n";
|
||||
stringstream ss;
|
||||
ss << "\nFollowing control commands are available:\n\n"
|
||||
<< "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device\n"
|
||||
<< "[k] increase log severity [l] decrease log severity [n] increase log verbosity [m] decrease log verbosity\n\n";
|
||||
cout << ss.str() << flush;
|
||||
}
|
||||
|
||||
auto Control::WaitForNextState() -> DeviceState
|
||||
@@ -206,7 +227,7 @@ auto Control::WaitForNextState() -> DeviceState
|
||||
unique_lock<mutex> lock{fEventsMutex};
|
||||
while (fEvents.empty())
|
||||
{
|
||||
fNewEvent.wait(lock);
|
||||
fNewEvent.wait_for(lock, chrono::milliseconds(50));
|
||||
}
|
||||
|
||||
auto result = fEvents.front();
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
#include <termios.h> // for the interactive mode
|
||||
#include <poll.h> // for the interactive mode
|
||||
@@ -109,12 +110,12 @@ auto DDS::HandleControl() -> void
|
||||
// and propagate addresses of bound channels to DDS.
|
||||
FillChannelContainers();
|
||||
|
||||
LOG(DEBUG) << "$DDS_TASK_PATH: " << getenv("DDS_TASK_PATH");
|
||||
LOG(DEBUG) << "$DDS_GROUP_NAME: " << getenv("DDS_GROUP_NAME");
|
||||
LOG(DEBUG) << "$DDS_COLLECTION_NAME: " << getenv("DDS_COLLECTION_NAME");
|
||||
LOG(DEBUG) << "$DDS_TASK_NAME: " << getenv("DDS_TASK_NAME");
|
||||
LOG(DEBUG) << "$DDS_TASK_INDEX: " << getenv("DDS_TASK_INDEX");
|
||||
LOG(DEBUG) << "$DDS_COLLECTION_INDEX: " << getenv("DDS_COLLECTION_INDEX");
|
||||
LOG(debug) << "$DDS_TASK_PATH: " << getenv("DDS_TASK_PATH");
|
||||
LOG(debug) << "$DDS_GROUP_NAME: " << getenv("DDS_GROUP_NAME");
|
||||
LOG(debug) << "$DDS_COLLECTION_NAME: " << getenv("DDS_COLLECTION_NAME");
|
||||
LOG(debug) << "$DDS_TASK_NAME: " << getenv("DDS_TASK_NAME");
|
||||
LOG(debug) << "$DDS_TASK_INDEX: " << getenv("DDS_TASK_INDEX");
|
||||
LOG(debug) << "$DDS_COLLECTION_INDEX: " << getenv("DDS_COLLECTION_INDEX");
|
||||
|
||||
// start DDS service - subscriptions will only start firing after this step
|
||||
fService.start();
|
||||
|
@@ -52,8 +52,8 @@ struct IofN
|
||||
, fEntries()
|
||||
{}
|
||||
|
||||
int fI;
|
||||
int fN;
|
||||
unsigned int fI;
|
||||
unsigned int fN;
|
||||
std::vector<std::string> fEntries;
|
||||
|
||||
};
|
||||
|
@@ -15,8 +15,8 @@ void addCustomOptions(bpo::options_description& options)
|
||||
{
|
||||
options.add_options()
|
||||
("out-channel", bpo::value<std::string>()->default_value("data"), "Name of the output channel")
|
||||
("same-msg", bpo::value<bool>()->default_value(true), "Re-send the same message (default), or recreate for each iteration")
|
||||
("msg-size", bpo::value<int>()->default_value(1000), "Message size in bytes")
|
||||
("same-msg", bpo::value<bool>()->default_value(false), "Re-send the same message, or recreate for each iteration")
|
||||
("msg-size", bpo::value<int>()->default_value(1000000), "Message size in bytes")
|
||||
("max-iterations", bpo::value<uint64_t>()->default_value(0), "Number of run iterations (0 - infinite)")
|
||||
("msg-rate", bpo::value<int>()->default_value(0), "Msg rate limit in maximum number of messages per second");
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ SAMPLER+=" --msg-size $msgSize"
|
||||
SAMPLER+=" --same-msg $sameMsg"
|
||||
# SAMPLER+=" --msg-rate 1000"
|
||||
SAMPLER+=" --max-iterations $maxIterations"
|
||||
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.01:5555"
|
||||
SAMPLER+=" --channel-config name=data,type=push,method=bind,address=tcp://127.0.0.1:5555"
|
||||
xterm -geometry 90x50+0+0 -hold -e $affinitySamp @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER &
|
||||
echo ""
|
||||
echo "started: xterm -geometry 90x50+0+0 -hold -e $affinitySamp @CMAKE_CURRENT_BINARY_DIR@/$SAMPLER"
|
||||
@@ -85,7 +85,7 @@ SINK+=" --id sink1"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --severity debug"
|
||||
SINK+=" --max-iterations $maxIterations"
|
||||
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.01:5555"
|
||||
SINK+=" --channel-config name=data,type=pull,method=connect,address=tcp://127.0.0.1:5555"
|
||||
xterm -geometry 90x50+550+0 -hold -e $affinitySink @CMAKE_CURRENT_BINARY_DIR@/$SINK &
|
||||
echo ""
|
||||
echo "started: xterm -geometry 90x50+550+0 -hold -e $affinitySink @CMAKE_CURRENT_BINARY_DIR@/$SINK"
|
||||
|
@@ -23,7 +23,7 @@ namespace bipc = boost::interprocess;
|
||||
namespace bpt = boost::posix_time;
|
||||
|
||||
atomic<bool> FairMQMessageSHM::fInterrupted(false);
|
||||
FairMQ::Transport FairMQMessageSHM::fTransportType = FairMQ::Transport::SHM;
|
||||
fair::mq::Transport FairMQMessageSHM::fTransportType = fair::mq::Transport::SHM;
|
||||
|
||||
FairMQMessageSHM::FairMQMessageSHM(Manager& manager)
|
||||
: fManager(manager)
|
||||
@@ -284,7 +284,7 @@ bool FairMQMessageSHM::SetUsedSize(const size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
FairMQ::Transport FairMQMessageSHM::GetType() const
|
||||
fair::mq::Transport FairMQMessageSHM::GetType() const
|
||||
{
|
||||
return fTransportType;
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ class FairMQMessageSHM : public FairMQMessage
|
||||
|
||||
bool SetUsedSize(const size_t size) override;
|
||||
|
||||
FairMQ::Transport GetType() const override;
|
||||
fair::mq::Transport GetType() const override;
|
||||
|
||||
void Copy(const FairMQMessage& msg) override;
|
||||
void Copy(const FairMQMessagePtr& msg) override;
|
||||
@@ -57,7 +57,7 @@ class FairMQMessageSHM : public FairMQMessage
|
||||
bool fQueued;
|
||||
bool fMetaCreated;
|
||||
static std::atomic<bool> fInterrupted;
|
||||
static FairMQ::Transport fTransportType;
|
||||
static fair::mq::Transport fTransportType;
|
||||
size_t fRegionId;
|
||||
mutable fair::mq::shmem::Region* fRegionPtr;
|
||||
boost::interprocess::managed_shared_memory::handle_t fHandle;
|
||||
|
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <zmq.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair::mq::shmem;
|
||||
|
||||
@@ -62,12 +64,18 @@ FairMQSocketSHM::FairMQSocketSHM(Manager& manager, const string& type, const str
|
||||
LOG(error) << "Failed setting ZMQ_RCVTIMEO socket option, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
|
||||
if (type == "sub")
|
||||
// if (type == "sub")
|
||||
// {
|
||||
// if (zmq_setsockopt(fSocket, ZMQ_SUBSCRIBE, nullptr, 0) != 0)
|
||||
// {
|
||||
// LOG(error) << "Failed setting ZMQ_SUBSCRIBE socket option, reason: " << zmq_strerror(errno);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (type == "sub" || type == "pub")
|
||||
{
|
||||
if (zmq_setsockopt(fSocket, ZMQ_SUBSCRIBE, nullptr, 0) != 0)
|
||||
{
|
||||
LOG(error) << "Failed setting ZMQ_SUBSCRIBE socket option, reason: " << zmq_strerror(errno);
|
||||
}
|
||||
LOG(error) << "PUB/SUB socket type is not supported for shared memory transport";
|
||||
throw fair::mq::SocketError("PUB/SUB socket type is not supported for shared memory transport");
|
||||
}
|
||||
|
||||
// LOG(info) << "created socket " << fId;
|
||||
@@ -188,7 +196,7 @@ int FairMQSocketSHM::ReceiveImpl(FairMQMessagePtr& msg, const int flags, const i
|
||||
const auto numMsgs = nbytes / sizeof(MetaHeader);
|
||||
if (numMsgs > 1)
|
||||
{
|
||||
LOG(ERROR) << "Receiving SHM multipart with a single message receive call";
|
||||
LOG(error) << "Receiving SHM multipart with a single message receive call";
|
||||
}
|
||||
|
||||
assert (numMsgs == 1);
|
||||
@@ -238,7 +246,7 @@ int FairMQSocketSHM::ReceiveImpl(FairMQMessagePtr& msg, const int flags, const i
|
||||
}
|
||||
}
|
||||
|
||||
int64_t FairMQSocketSHM::SendImpl(vector<FairMQMessagePtr>& msgVec, const int flags, const int timeout)
|
||||
int64_t FairMQSocketSHM::SendImpl(vector<FairMQMessagePtr>& msgVec, const int flags, const int /*timeout*/)
|
||||
{
|
||||
const unsigned int vecSize = msgVec.size();
|
||||
int64_t totalSize = 0;
|
||||
@@ -303,13 +311,13 @@ int64_t FairMQSocketSHM::SendImpl(vector<FairMQMessagePtr>& msgVec, const int fl
|
||||
else if (zmq_errno() == ETERM)
|
||||
{
|
||||
zmq_msg_close (&lZmqMsg);
|
||||
LOG(INFO) << "terminating socket " << fId;
|
||||
LOG(info) << "terminating socket " << fId;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
zmq_msg_close (&lZmqMsg);
|
||||
LOG(ERROR) << "Failed sending on socket " << fId << ", reason: " << zmq_strerror(errno);
|
||||
LOG(error) << "Failed sending on socket " << fId << ", reason: " << zmq_strerror(errno);
|
||||
return nbytes;
|
||||
}
|
||||
}
|
||||
@@ -318,7 +326,7 @@ int64_t FairMQSocketSHM::SendImpl(vector<FairMQMessagePtr>& msgVec, const int fl
|
||||
}
|
||||
|
||||
|
||||
int64_t FairMQSocketSHM::ReceiveImpl(vector<FairMQMessagePtr>& msgVec, const int flags, const int timeout)
|
||||
int64_t FairMQSocketSHM::ReceiveImpl(vector<FairMQMessagePtr>& msgVec, const int flags, const int /*timeout*/)
|
||||
{
|
||||
int64_t totalSize = 0;
|
||||
|
||||
|
@@ -32,7 +32,7 @@ namespace bfs = boost::filesystem;
|
||||
namespace bpt = boost::posix_time;
|
||||
namespace bipc = boost::interprocess;
|
||||
|
||||
FairMQ::Transport FairMQTransportFactorySHM::fTransportType = FairMQ::Transport::SHM;
|
||||
fair::mq::Transport FairMQTransportFactorySHM::fTransportType = fair::mq::Transport::SHM;
|
||||
|
||||
FairMQTransportFactorySHM::FairMQTransportFactorySHM(const string& id, const FairMQProgOptions* config)
|
||||
: FairMQTransportFactory(id)
|
||||
@@ -69,14 +69,14 @@ FairMQTransportFactorySHM::FairMQTransportFactorySHM(const string& id, const Fai
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(warn) << "FairMQProgOptions not available! Using defaults.";
|
||||
LOG(debug) << "FairMQProgOptions not available! Using defaults.";
|
||||
}
|
||||
|
||||
fSessionName.resize(8, '_'); // shorten the session name, to accommodate for name size limit on some systems (MacOS)
|
||||
|
||||
try
|
||||
{
|
||||
fShMutex = fair::mq::tools::make_unique<bipc::named_mutex>(bipc::open_or_create, string("fmq_shm_" + fSessionName + "_mutex").c_str());
|
||||
fShMutex = fair::mq::tools::make_unique<bipc::named_mutex>(bipc::open_or_create, string("fmq_" + fSessionName + "_mtx").c_str());
|
||||
|
||||
if (zmq_ctx_set(fContext, ZMQ_IO_THREADS, numIoThreads) != 0)
|
||||
{
|
||||
@@ -90,7 +90,7 @@ FairMQTransportFactorySHM::FairMQTransportFactorySHM(const string& id, const Fai
|
||||
}
|
||||
|
||||
fManager = fair::mq::tools::make_unique<Manager>(fSessionName, segmentSize);
|
||||
LOG(debug) << "created/opened shared memory segment '" << "fmq_shm_" << fSessionName << "_main" << "' of " << segmentSize << " bytes. Available are " << fManager->Segment().get_free_memory() << " bytes.";
|
||||
LOG(debug) << "created/opened shared memory segment '" << "fmq_" << fSessionName << "_main" << "' of " << segmentSize << " bytes. Available are " << fManager->Segment().get_free_memory() << " bytes.";
|
||||
|
||||
{
|
||||
bipc::scoped_lock<bipc::named_mutex> lock(*fShMutex);
|
||||
@@ -149,14 +149,14 @@ void FairMQTransportFactorySHM::StartMonitor()
|
||||
|
||||
auto env = boost::this_process::environment();
|
||||
|
||||
vector<boost::filesystem::path> ownPath = boost::this_process::path();
|
||||
vector<bfs::path> ownPath = boost::this_process::path();
|
||||
|
||||
if (const char* fmqp = getenv("FAIRMQ_PATH"))
|
||||
{
|
||||
ownPath.insert(ownPath.begin(), boost::filesystem::path(fmqp));
|
||||
ownPath.insert(ownPath.begin(), bfs::path(fmqp));
|
||||
}
|
||||
|
||||
boost::filesystem::path p = boost::process::search_path("fairmq-shmmonitor", ownPath);
|
||||
bfs::path p = boost::process::search_path("fairmq-shmmonitor", ownPath);
|
||||
|
||||
if (!p.empty())
|
||||
{
|
||||
@@ -184,13 +184,13 @@ void FairMQTransportFactorySHM::StartMonitor()
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARN) << "could not find fairmq-shmmonitor in the path";
|
||||
LOG(warn) << "could not find fairmq-shmmonitor in the path";
|
||||
}
|
||||
}
|
||||
|
||||
void FairMQTransportFactorySHM::SendHeartbeats()
|
||||
{
|
||||
string controlQueueName("fmq_shm_" + fSessionName + "_control_queue");
|
||||
string controlQueueName("fmq_" + fSessionName + "_cq");
|
||||
while (fSendHeartbeats)
|
||||
{
|
||||
try
|
||||
@@ -312,11 +312,11 @@ FairMQTransportFactorySHM::~FairMQTransportFactorySHM()
|
||||
|
||||
if (lastRemoved)
|
||||
{
|
||||
boost::interprocess::named_mutex::remove(string("fmq_shm_" + fSessionName + "_mutex").c_str());
|
||||
boost::interprocess::named_mutex::remove(string("fmq_" + fSessionName + "_mtx").c_str());
|
||||
}
|
||||
}
|
||||
|
||||
FairMQ::Transport FairMQTransportFactorySHM::GetType() const
|
||||
fair::mq::Transport FairMQTransportFactorySHM::GetType() const
|
||||
{
|
||||
return fTransportType;
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ class FairMQTransportFactorySHM : public FairMQTransportFactory
|
||||
|
||||
FairMQUnmanagedRegionPtr CreateUnmanagedRegion(const size_t size, FairMQRegionCallback callback = nullptr) const override;
|
||||
|
||||
FairMQ::Transport GetType() const override;
|
||||
fair::mq::Transport GetType() const override;
|
||||
|
||||
void Interrupt() override { FairMQSocketSHM::Interrupt(); }
|
||||
void Resume() override { FairMQSocketSHM::Resume(); }
|
||||
@@ -58,7 +58,7 @@ class FairMQTransportFactorySHM : public FairMQTransportFactory
|
||||
void SendHeartbeats();
|
||||
void StartMonitor();
|
||||
|
||||
static FairMQ::Transport fTransportType;
|
||||
static fair::mq::Transport fTransportType;
|
||||
std::string fDeviceId;
|
||||
std::string fSessionName;
|
||||
void* fContext;
|
||||
|
@@ -23,8 +23,8 @@ std::unordered_map<uint64_t, Region> Manager::fRegions;
|
||||
|
||||
Manager::Manager(const string& name, size_t size)
|
||||
: fSessionName(name)
|
||||
, fSegmentName("fmq_shm_" + fSessionName + "_main")
|
||||
, fManagementSegmentName("fmq_shm_" + fSessionName + "_management")
|
||||
, fSegmentName("fmq_" + fSessionName + "_main")
|
||||
, fManagementSegmentName("fmq_" + fSessionName + "_mng")
|
||||
, fSegment(bipc::open_or_create, fSegmentName.c_str(), size)
|
||||
, fManagementSegment(bipc::open_or_create, fManagementSegmentName.c_str(), 65536)
|
||||
{}
|
||||
|
@@ -59,9 +59,9 @@ Monitor::Monitor(const string& sessionName, bool selfDestruct, bool interactive,
|
||||
, fCleanOnExit(cleanOnExit)
|
||||
, fTimeoutInMS(timeoutInMS)
|
||||
, fSessionName(sessionName)
|
||||
, fSegmentName("fmq_shm_" + fSessionName + "_main")
|
||||
, fManagementSegmentName("fmq_shm_" + fSessionName + "_management")
|
||||
, fControlQueueName("fmq_shm_" + fSessionName + "_control_queue")
|
||||
, fSegmentName("fmq_" + fSessionName + "_main")
|
||||
, fManagementSegmentName("fmq_" + fSessionName + "_mng")
|
||||
, fControlQueueName("fmq_" + fSessionName + "_cq")
|
||||
, fTerminating(false)
|
||||
, fHeartbeatTriggered(false)
|
||||
, fLastHeartbeat(chrono::high_resolution_clock::now())
|
||||
@@ -170,6 +170,7 @@ void Monitor::Interactive()
|
||||
struct termios t;
|
||||
tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure
|
||||
t.c_lflag &= ~ICANON; // disable canonical input
|
||||
t.c_lflag &= ~ECHO; // do not echo input chars
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings
|
||||
|
||||
cout << endl;
|
||||
@@ -238,6 +239,7 @@ void Monitor::Interactive()
|
||||
|
||||
tcgetattr(STDIN_FILENO, &t); // get the current terminal I/O structure
|
||||
t.c_lflag |= ICANON; // re-enable canonical input
|
||||
t.c_lflag |= ECHO; // echo input chars
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &t); // apply the new settings
|
||||
}
|
||||
|
||||
@@ -360,7 +362,7 @@ void Monitor::CheckSegment()
|
||||
|
||||
void Monitor::Cleanup(const string& sessionName)
|
||||
{
|
||||
string managementSegmentName("fmq_shm_" + sessionName + "_management");
|
||||
string managementSegmentName("fmq_" + sessionName + "_mng");
|
||||
try
|
||||
{
|
||||
bipc::managed_shared_memory managementSegment(bipc::open_only, managementSegmentName.c_str());
|
||||
@@ -371,8 +373,8 @@ void Monitor::Cleanup(const string& sessionName)
|
||||
unsigned int regionCount = rc->fCount;
|
||||
for (unsigned int i = 1; i <= regionCount; ++i)
|
||||
{
|
||||
RemoveObject("fmq_shm_" + sessionName + "_region_" + to_string(i));
|
||||
RemoveQueue(string("fmq_shm_" + sessionName + "_region_queue_" + to_string(i)));
|
||||
RemoveObject("fmq_" + sessionName + "_rg_" + to_string(i));
|
||||
RemoveQueue(string("fmq_" + sessionName + "_rgq_" + to_string(i)));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -387,9 +389,9 @@ void Monitor::Cleanup(const string& sessionName)
|
||||
cout << "Did not find '" << managementSegmentName << "' shared memory segment. No regions to cleanup." << endl;
|
||||
}
|
||||
|
||||
RemoveObject("fmq_shm_" + sessionName + "_main");
|
||||
RemoveObject("fmq_" + sessionName + "_main");
|
||||
|
||||
boost::interprocess::named_mutex::remove(string("fmq_shm_" + sessionName + "_mutex").c_str());
|
||||
boost::interprocess::named_mutex::remove(string("fmq_" + sessionName + "_mtx").c_str());
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
@@ -425,7 +427,7 @@ void Monitor::PrintQueues()
|
||||
try
|
||||
{
|
||||
bipc::managed_shared_memory segment(bipc::open_only, fSegmentName.c_str());
|
||||
StringVector* queues = segment.find<StringVector>(string("fmq_shm_" + fSessionName + "_queues").c_str()).first;
|
||||
StringVector* queues = segment.find<StringVector>(string("fmq_" + fSessionName + "_qs").c_str()).first;
|
||||
if (queues)
|
||||
{
|
||||
cout << "found " << queues->size() << " queue(s):" << endl;
|
||||
|
@@ -27,9 +27,9 @@ The Monitor class can also be used independently from the supplied executable (b
|
||||
|
||||
FairMQ Shared Memory currently uses following names to register shared memory on the system:
|
||||
|
||||
`fmq_shm_<sessionName>_main` - main segment name, used for user data (session name can be overridden via `--session`).
|
||||
`fmq_shm_<sessionName>_management` - management segment name, used for storing management data.
|
||||
`fmq_shm_<sessionName>_control_queue` - message queue for communicating between shm transport and shm monitor (exists independent of above segments).
|
||||
`fmq_shm_<sessionName>_mutex` - boost::interprocess::named_mutex for management purposes (exists independent of above segments).
|
||||
`fmq_shm_<sessionName>_region_<index>` - names of unmanaged regions.
|
||||
`fmq_shm_<sessionName>_region_queue_<index>` - names of queues for the unmanaged regions.
|
||||
`fmq_<sessionName>_main` - main segment name, used for user data (session name can be overridden via `--session`).
|
||||
`fmq_<sessionName>_mng` - management segment name, used for storing management data.
|
||||
`fmq_<sessionName>_cq` - message queue for communicating between shm transport and shm monitor (exists independent of above segments).
|
||||
`fmq_<sessionName>_mtx` - boost::interprocess::named_mutex for management purposes (exists independent of above segments).
|
||||
`fmq_<sessionName>_rg_<index>` - names of unmanaged regions.
|
||||
`fmq_<sessionName>_rgq_<index>` - names of queues for the unmanaged regions.
|
||||
|
@@ -28,8 +28,8 @@ Region::Region(Manager& manager, uint64_t id, uint64_t size, bool remote, FairMQ
|
||||
: fManager(manager)
|
||||
, fRemote(remote)
|
||||
, fStop(false)
|
||||
, fName("fmq_shm_" + fManager.fSessionName +"_region_" + to_string(id))
|
||||
, fQueueName("fmq_shm_" + fManager.fSessionName +"_region_queue_" + to_string(id))
|
||||
, fName("fmq_" + fManager.fSessionName +"_rg_" + to_string(id))
|
||||
, fQueueName("fmq_" + fManager.fSessionName +"_rgq_" + to_string(id))
|
||||
, fShmemObject()
|
||||
, fQueue(nullptr)
|
||||
, fWorker()
|
||||
@@ -53,7 +53,7 @@ Region::Region(Manager& manager, uint64_t id, uint64_t size, bool remote, FairMQ
|
||||
LOG(debug) << "shmem: created region queue: " << fQueueName;
|
||||
}
|
||||
fRegion = bipc::mapped_region(fShmemObject, bipc::read_write); // TODO: add HUGEPAGES flag here
|
||||
// fRegion = bipc::mapped_region(fShmemObject, bipc::read_write, 0, 0, 0, MAP_HUGETLB | MAP_HUGE_1GB);
|
||||
// fRegion = bipc::mapped_region(fShmemObject, bipc::read_write, 0, 0, 0, MAP_ANONYMOUS | MAP_HUGETLB);
|
||||
}
|
||||
|
||||
void Region::StartReceivingAcks()
|
||||
|
@@ -108,7 +108,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
cout << "Cleaning up \"" << sessionName << "\"..." << endl;
|
||||
fair::mq::shmem::Monitor::Cleanup(sessionName);
|
||||
fair::mq::shmem::Monitor::RemoveQueue("fmq_shm_" + sessionName + "_control_queue");
|
||||
fair::mq::shmem::Monitor::RemoveQueue("fmq_" + sessionName + "_cq");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
192
fairmq/tools/Network.cxx
Normal file
192
fairmq/tools/Network.cxx
Normal file
@@ -0,0 +1,192 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <fairmq/tools/Network.h>
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST
|
||||
#endif
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp> // trim
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
// returns a map with network interface names as keys and their IP addresses as values
|
||||
int getHostIPs(map<string, string>& addressMap)
|
||||
{
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
int s;
|
||||
char host[NI_MAXHOST];
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1)
|
||||
{
|
||||
perror("getifaddrs");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (ifa->ifa_addr == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
{
|
||||
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
||||
if (s != 0)
|
||||
{
|
||||
cout << "getnameinfo() failed: " << gai_strerror(s) << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
addressMap.insert(pair<string, string>(ifa->ifa_name, host));
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get IP address of a given interface name
|
||||
string getInterfaceIP(const string& interface)
|
||||
{
|
||||
map<string, string> IPs;
|
||||
getHostIPs(IPs);
|
||||
if (IPs.count(interface))
|
||||
{
|
||||
return IPs[interface];
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "Could not find provided network interface: \"" << interface << "\"!, exiting.";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// get name of the default route interface
|
||||
string getDefaultRouteNetworkInterface()
|
||||
{
|
||||
array<char, 128> buffer;
|
||||
string interfaceName;
|
||||
|
||||
#ifdef __APPLE__ // MacOS
|
||||
unique_ptr<FILE, decltype(pclose) *> file(popen("route -n get default | grep interface | cut -d \":\" -f 2", "r"), pclose);
|
||||
#else // Linux
|
||||
unique_ptr<FILE, decltype(pclose) *> file(popen("ip route | grep default | cut -d \" \" -f 5 | head -n 1", "r"), pclose);
|
||||
#endif
|
||||
|
||||
if (!file)
|
||||
{
|
||||
LOG(error) << "Could not detect default route network interface name - popen() failed!";
|
||||
return "";
|
||||
}
|
||||
|
||||
while (!feof(file.get()))
|
||||
{
|
||||
if (fgets(buffer.data(), 128, file.get()) != NULL)
|
||||
{
|
||||
interfaceName += buffer.data();
|
||||
}
|
||||
}
|
||||
|
||||
boost::algorithm::trim(interfaceName);
|
||||
|
||||
if (interfaceName == "")
|
||||
{
|
||||
LOG(error) << "Could not detect default route network interface name";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(debug) << "Detected network interface name for the default route: " << interfaceName;
|
||||
}
|
||||
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
string getIpFromHostname(const string& hostname)
|
||||
{
|
||||
try {
|
||||
namespace bai = boost::asio::ip;
|
||||
boost::asio::io_service ios;
|
||||
bai::tcp::resolver resolver(ios);
|
||||
bai::tcp::resolver::query query(hostname, "");
|
||||
bai::tcp::resolver::iterator end;
|
||||
|
||||
auto it = find_if(static_cast<bai::basic_resolver_iterator<bai::tcp>>(resolver.resolve(query)), end, [](const bai::tcp::endpoint& ep) {
|
||||
return ep.address().is_v4();
|
||||
});
|
||||
|
||||
if (it != end) {
|
||||
stringstream ss;
|
||||
ss << static_cast<bai::tcp::endpoint>(*it).address();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'";
|
||||
|
||||
return "";
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
string getIpFromHostname(const string& hostname, boost::asio::io_service& ios)
|
||||
{
|
||||
try {
|
||||
namespace bai = boost::asio::ip;
|
||||
bai::tcp::resolver resolver(ios);
|
||||
bai::tcp::resolver::query query(hostname, "");
|
||||
bai::tcp::resolver::iterator end;
|
||||
|
||||
auto it = find_if(static_cast<bai::basic_resolver_iterator<bai::tcp>>(resolver.resolve(query)), end, [](const bai::tcp::endpoint& ep) {
|
||||
return ep.address().is_v4();
|
||||
});
|
||||
|
||||
if (it != end) {
|
||||
stringstream ss;
|
||||
ss << static_cast<bai::tcp::endpoint>(*it).address();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'";
|
||||
|
||||
return "";
|
||||
} catch (exception& e) {
|
||||
LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace tools */
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
@@ -9,26 +9,20 @@
|
||||
#ifndef FAIR_MQ_TOOLS_NETWORK_H
|
||||
#define FAIR_MQ_TOOLS_NETWORK_H
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST
|
||||
#endif
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp> // trim
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
|
||||
// forward declarations
|
||||
namespace boost
|
||||
{
|
||||
namespace asio
|
||||
{
|
||||
|
||||
class io_context;
|
||||
typedef class io_context io_service;
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
namespace fair
|
||||
{
|
||||
@@ -38,150 +32,17 @@ namespace tools
|
||||
{
|
||||
|
||||
// returns a map with network interface names as keys and their IP addresses as values
|
||||
inline int getHostIPs(std::map<std::string, std::string>& addressMap)
|
||||
{
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
int s;
|
||||
char host[NI_MAXHOST];
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1)
|
||||
{
|
||||
perror("getifaddrs");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (ifa->ifa_addr == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
{
|
||||
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
||||
if (s != 0)
|
||||
{
|
||||
std::cout << "getnameinfo() failed: " << gai_strerror(s) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
addressMap.insert(std::pair<std::string, std::string>(ifa->ifa_name, host));
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int getHostIPs(std::map<std::string, std::string>& addressMap);
|
||||
|
||||
// get IP address of a given interface name
|
||||
inline std::string getInterfaceIP(std::string interface)
|
||||
{
|
||||
std::map<std::string, std::string> IPs;
|
||||
getHostIPs(IPs);
|
||||
if (IPs.count(interface))
|
||||
{
|
||||
return IPs[interface];
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(error) << "Could not find provided network interface: \"" << interface << "\"!, exiting.";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
std::string getInterfaceIP(const std::string& interface);
|
||||
|
||||
// get name of the default route interface
|
||||
inline std::string getDefaultRouteNetworkInterface()
|
||||
{
|
||||
std::array<char, 128> buffer;
|
||||
std::string interfaceName;
|
||||
std::string getDefaultRouteNetworkInterface();
|
||||
|
||||
#ifdef __APPLE__ // MacOS
|
||||
std::unique_ptr<FILE, decltype(pclose) *> file(popen("route -n get default | grep interface | cut -d \":\" -f 2", "r"), pclose);
|
||||
#else // Linux
|
||||
std::unique_ptr<FILE, decltype(pclose) *> file(popen("ip route | grep default | cut -d \" \" -f 5 | head -n 1", "r"), pclose);
|
||||
#endif
|
||||
std::string getIpFromHostname(const std::string& hostname);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
LOG(error) << "Could not detect default route network interface name - popen() failed!";
|
||||
return "";
|
||||
}
|
||||
|
||||
while (!feof(file.get()))
|
||||
{
|
||||
if (fgets(buffer.data(), 128, file.get()) != NULL)
|
||||
{
|
||||
interfaceName += buffer.data();
|
||||
}
|
||||
}
|
||||
|
||||
boost::algorithm::trim(interfaceName);
|
||||
|
||||
if (interfaceName == "")
|
||||
{
|
||||
LOG(error) << "Could not detect default route network interface name";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(debug) << "Detected network interface name for the default route: " << interfaceName;
|
||||
}
|
||||
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
inline std::string getIpFromHostname(const std::string& hostname)
|
||||
{
|
||||
try {
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver resolver(ios);
|
||||
boost::asio::ip::tcp::resolver::query query(hostname, "");
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
|
||||
auto it = std::find_if(resolver.resolve(query), end, [](const boost::asio::ip::tcp::endpoint& ep) {
|
||||
return ep.address().is_v4();
|
||||
});
|
||||
|
||||
if (it != end) {
|
||||
std::stringstream ss;
|
||||
ss << static_cast<boost::asio::ip::tcp::endpoint>(*it).address();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'";
|
||||
|
||||
return "";
|
||||
} catch (std::exception& e) {
|
||||
LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string getIpFromHostname(const std::string& hostname, boost::asio::io_service& ios)
|
||||
{
|
||||
try {
|
||||
boost::asio::ip::tcp::resolver resolver(ios);
|
||||
boost::asio::ip::tcp::resolver::query query(hostname, "");
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
|
||||
auto it = std::find_if(resolver.resolve(query), end, [](const boost::asio::ip::tcp::endpoint& ep) {
|
||||
return ep.address().is_v4();
|
||||
});
|
||||
|
||||
if (it != end) {
|
||||
std::stringstream ss;
|
||||
ss << static_cast<boost::asio::ip::tcp::endpoint>(*it).address();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'";
|
||||
|
||||
return "";
|
||||
} catch (std::exception& e) {
|
||||
LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
std::string getIpFromHostname(const std::string& hostname, boost::asio::io_service& ios);
|
||||
|
||||
} /* namespace tools */
|
||||
} /* namespace mq */
|
||||
|
73
fairmq/tools/Process.cxx
Normal file
73
fairmq/tools/Process.cxx
Normal file
@@ -0,0 +1,73 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <fairmq/tools/Process.h>
|
||||
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
/**
|
||||
* Execute given command in forked process and capture stdout output
|
||||
* and exit code.
|
||||
*
|
||||
* @param[in] cmd Command to execute
|
||||
* @param[in] log_prefix How to prefix each captured output line with
|
||||
* @return Captured stdout output and exit code
|
||||
*/
|
||||
execute_result execute(string cmd, string prefix)
|
||||
{
|
||||
execute_result result;
|
||||
stringstream out;
|
||||
|
||||
// print full line thread-safe
|
||||
stringstream printCmd;
|
||||
printCmd << prefix << cmd << "\n";
|
||||
cout << printCmd.str() << flush;
|
||||
|
||||
out << prefix << cmd << endl;
|
||||
|
||||
// Execute command and capture stdout, add prefix line by line
|
||||
boost::process::ipstream stdout;
|
||||
boost::process::child c(cmd, boost::process::std_out > stdout);
|
||||
string line;
|
||||
while (getline(stdout, line))
|
||||
{
|
||||
// print full line thread-safe
|
||||
stringstream printLine;
|
||||
printLine << prefix << line << "\n";
|
||||
cout << printLine.str() << flush;
|
||||
|
||||
out << prefix << line << "\n";
|
||||
}
|
||||
|
||||
c.wait();
|
||||
|
||||
// Capture exit code
|
||||
result.exit_code = c.exit_code();
|
||||
out << prefix << " Exit code: " << result.exit_code << endl;
|
||||
|
||||
result.console_out = out.str();
|
||||
|
||||
// Return result
|
||||
return result;
|
||||
}
|
||||
|
||||
} /* namespace tools */
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
@@ -9,8 +9,6 @@
|
||||
#ifndef FAIR_MQ_TOOLS_PROCESS_H
|
||||
#define FAIR_MQ_TOOLS_PROCESS_H
|
||||
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace fair
|
||||
@@ -37,43 +35,7 @@ struct execute_result
|
||||
* @param[in] log_prefix How to prefix each captured output line with
|
||||
* @return Captured stdout output and exit code
|
||||
*/
|
||||
inline execute_result execute(std::string cmd, std::string prefix = "")
|
||||
{
|
||||
execute_result result;
|
||||
std::stringstream out;
|
||||
|
||||
// print full line thread-safe
|
||||
std::stringstream printCmd;
|
||||
printCmd << prefix << cmd << "\n";
|
||||
std::cout << printCmd.str() << std::flush;
|
||||
|
||||
out << prefix << cmd << std::endl;
|
||||
|
||||
// Execute command and capture stdout, add prefix line by line
|
||||
boost::process::ipstream stdout;
|
||||
boost::process::child c(cmd, boost::process::std_out > stdout);
|
||||
std::string line;
|
||||
while (getline(stdout, line))
|
||||
{
|
||||
// print full line thread-safe
|
||||
std::stringstream printLine;
|
||||
printLine << prefix << line << "\n";
|
||||
std::cout << printLine.str() << std::flush;
|
||||
|
||||
out << prefix << line << "\n";
|
||||
}
|
||||
|
||||
c.wait();
|
||||
|
||||
// Capture exit code
|
||||
result.exit_code = c.exit_code();
|
||||
out << prefix << " Exit code: " << result.exit_code << std::endl;
|
||||
|
||||
result.console_out = out.str();
|
||||
|
||||
// Return result
|
||||
return result;
|
||||
}
|
||||
execute_result execute(std::string cmd, std::string prefix = "");
|
||||
|
||||
} /* namespace tools */
|
||||
} /* namespace mq */
|
||||
|
44
fairmq/tools/Unique.cxx
Normal file
44
fairmq/tools/Unique.cxx
Normal file
@@ -0,0 +1,44 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <fairmq/tools/Unique.h>
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
// generates UUID string
|
||||
string Uuid()
|
||||
{
|
||||
boost::uuids::random_generator gen;
|
||||
boost::uuids::uuid u = gen();
|
||||
return boost::uuids::to_string(u);
|
||||
}
|
||||
|
||||
// generates UUID and returns its hash
|
||||
size_t UuidHash()
|
||||
{
|
||||
boost::uuids::random_generator gen;
|
||||
boost::hash<boost::uuids::uuid> uuid_hasher;
|
||||
boost::uuids::uuid u = gen();
|
||||
return uuid_hasher(u);
|
||||
}
|
||||
|
||||
} /* namespace tools */
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
@@ -9,11 +9,6 @@
|
||||
#ifndef FAIR_MQ_TOOLS_UNIQUE_H
|
||||
#define FAIR_MQ_TOOLS_UNIQUE_H
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace fair
|
||||
@@ -24,21 +19,10 @@ namespace tools
|
||||
{
|
||||
|
||||
// generates UUID string
|
||||
inline std::string Uuid()
|
||||
{
|
||||
boost::uuids::random_generator gen;
|
||||
boost::uuids::uuid u = gen();
|
||||
return boost::uuids::to_string(u);
|
||||
}
|
||||
std::string Uuid();
|
||||
|
||||
// generates UUID and returns its hash
|
||||
inline std::size_t UuidHash()
|
||||
{
|
||||
boost::uuids::random_generator gen;
|
||||
boost::hash<boost::uuids::uuid> uuid_hasher;
|
||||
boost::uuids::uuid u = gen();
|
||||
return uuid_hasher(u);
|
||||
}
|
||||
std::size_t UuidHash();
|
||||
|
||||
} /* namespace tools */
|
||||
} /* namespace mq */
|
||||
|
@@ -18,9 +18,11 @@
|
||||
#include <fairmq/Tools.h>
|
||||
#include "FairMQUnmanagedRegionZMQ.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQ::Transport FairMQMessageZMQ::fTransportType = FairMQ::Transport::ZMQ;
|
||||
fair::mq::Transport FairMQMessageZMQ::fTransportType = fair::mq::Transport::ZMQ;
|
||||
|
||||
FairMQMessageZMQ::FairMQMessageZMQ()
|
||||
: fUsedSizeModified(false)
|
||||
@@ -190,7 +192,7 @@ void FairMQMessageZMQ::ApplyUsedSize()
|
||||
}
|
||||
}
|
||||
|
||||
FairMQ::Transport FairMQMessageZMQ::GetType() const
|
||||
fair::mq::Transport FairMQMessageZMQ::GetType() const
|
||||
{
|
||||
return fTransportType;
|
||||
}
|
||||
|
@@ -46,7 +46,7 @@ class FairMQMessageZMQ : public FairMQMessage
|
||||
bool SetUsedSize(const size_t size) override;
|
||||
void ApplyUsedSize();
|
||||
|
||||
FairMQ::Transport GetType() const override;
|
||||
fair::mq::Transport GetType() const override;
|
||||
|
||||
void Copy(const FairMQMessagePtr& msg) override;
|
||||
void Copy(const FairMQMessage& msg) override;
|
||||
@@ -58,7 +58,7 @@ class FairMQMessageZMQ : public FairMQMessage
|
||||
size_t fUsedSize;
|
||||
std::unique_ptr<zmq_msg_t> fMsg;
|
||||
std::unique_ptr<zmq_msg_t> fViewMsg; // view on a subset of fMsg (treating it as user buffer)
|
||||
static FairMQ::Transport fTransportType;
|
||||
static fair::mq::Transport fTransportType;
|
||||
|
||||
zmq_msg_t* GetMessage() const;
|
||||
void CloseMessage();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user