Permalink
Fetching contributors…
Cannot retrieve contributors at this time
1074 lines (1028 sloc) 50.1 KB
/* -*-Mode:C++;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
* ex: set ft=cpp fenc=utf-8 sts=4 ts=4 sw=4 et nomod:
*
* MIT License
*
* Copyright (c) 2012-2017 Michael Truog <mjtruog at gmail dot com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "cloudi.hpp"
#include "thread_pool.hpp"
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <sstream>
#include "assert.hpp"
class ThreadData
{
};
class OutputData
{
public:
OutputData & setError(int value)
{
m_error = value;
return *this;
}
int error() const { return m_error; }
private:
int m_error;
};
class Input
{
public:
Input(unsigned int const thread_index) :
m_stop_default(false),
m_stop(m_stop_default),
m_api(thread_index),
m_thread_index(thread_index)
{
}
uint32_t timeout_terminate() const
{
return m_api.timeout_terminate();
}
OutputData process(bool const & stop, ThreadData & /*data*/)
{
int result;
result = m_api.subscribe("a/b/c/d", *this,
&Input::sequence1_abcd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/b/c/*", *this,
&Input::sequence1_abc_);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/b/*/d", *this,
&Input::sequence1_ab_d);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/*/c/d", *this,
&Input::sequence1_a_cd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*/b/c/d", *this,
&Input::sequence1__bcd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/b/*", *this,
&Input::sequence1_ab__);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/*/d", *this,
&Input::sequence1_a__d);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*/c/d", *this,
&Input::sequence1___cd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/*", *this,
&Input::sequence1_a___);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*/d", *this,
&Input::sequence1____d);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*", *this,
&Input::sequence1_____);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("sequence1", *this,
&Input::sequence1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e2);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e3);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e4);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e5);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e6);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e7);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&Input::sequence2_e8);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("sequence2", *this,
&Input::sequence2);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("f1", *this,
&Input::sequence3_f1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("f2", *this,
&Input::sequence3_f2);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("g1", *this,
&Input::sequence3_g1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("sequence3", *this,
&Input::sequence3);
assert(result == CloudI::API::return_value::success);
if (m_thread_index == 0)
{
result = m_api.send_async(std::string(m_api.prefix()) +
"sequence1", "start", 6);
assert(result == CloudI::API::return_value::success);
}
OutputData resultObject;
int value;
m_stop = stop;
while (CloudI::API::return_value::timeout ==
(value = m_api.poll(1000)))
{
if (stop)
return resultObject.setError(
CloudI::API::return_value::success);
}
return resultObject.setError(value);
}
private:
void sequence1_abcd(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/b/c/d"));
assert(request_size == 6);
assert(::memcmp(request, "test1", 6) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_abc_(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/b/c/*"));
assert(request_size == 6);
assert(::memcmp(request, "test2", 6) == 0 ||
::memcmp(request, "test3", 6) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_ab_d(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/b/*/d"));
assert(request_size == 6);
assert(::memcmp(request, "test4", 6) == 0 ||
::memcmp(request, "test5", 6) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_a_cd(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/*/c/d"));
assert(request_size == 6);
assert(::memcmp(request, "test6", 6) == 0 ||
::memcmp(request, "test7", 6) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1__bcd(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "*/b/c/d"));
assert(request_size == 6);
assert(::memcmp(request, "test8", 6) == 0 ||
::memcmp(request, "test9", 6) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_ab__(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/b/*"));
assert(request_size == 7);
assert(::memcmp(request, "test10", 7) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_a__d(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/*/d"));
assert(request_size == 7);
assert(::memcmp(request, "test11", 7) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1___cd(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "*/c/d"));
assert(request_size == 7);
assert(::memcmp(request, "test12", 7) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_a___(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "a/*"));
assert(request_size == 7);
assert(::memcmp(request, "test13", 7) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1____d(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "*/d"));
assert(request_size == 7);
assert(::memcmp(request, "test14", 7) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1_____(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(pattern == (std::string(api.prefix()) + "*"));
assert(request_size == 7);
assert(::memcmp(request, "test15", 7) == 0);
api.return_(request_type, name, pattern,
"", 0, request, request_size,
timeout, trans_id, pid, pid_size);
}
void sequence1(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
int result;
result = api.recv_async(1000);
assert(result == CloudI::API::return_value::success);
while (::memcmp(api.get_response(), "end", 4) == 0)
{
// consume "end" and sleep
result = api.recv_async(1000);
assert(result == CloudI::API::return_value::success);
}
std::cout << "messaging sequence1 start c++" << std::endl;
assert(request_size == 6);
assert(::memcmp(request, "start", 6) == 0);
result = api.send_async(std::string(api.prefix()) + "a/b/c/d",
"test1", 6);
assert(result == CloudI::API::return_value::success);
char test1_id[16];
::memcpy(test1_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/b/c/z",
"test2", 6);
assert(result == CloudI::API::return_value::success);
char test2_id[16];
::memcpy(test2_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/b/c/dd",
"test3", 6);
assert(result == CloudI::API::return_value::success);
char test3_id[16];
::memcpy(test3_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/b/z/d",
"test4", 6);
assert(result == CloudI::API::return_value::success);
char test4_id[16];
::memcpy(test4_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/b/cc/d",
"test5", 6);
assert(result == CloudI::API::return_value::success);
char test5_id[16];
::memcpy(test5_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/z/c/d",
"test6", 6);
assert(result == CloudI::API::return_value::success);
char test6_id[16];
::memcpy(test6_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/bb/c/d",
"test7", 6);
assert(result == CloudI::API::return_value::success);
char test7_id[16];
::memcpy(test7_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "z/b/c/d",
"test8", 6);
assert(result == CloudI::API::return_value::success);
char test8_id[16];
::memcpy(test8_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "aa/b/c/d",
"test9", 6);
assert(result == CloudI::API::return_value::success);
char test9_id[16];
::memcpy(test9_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/b/czd",
"test10", 7);
assert(result == CloudI::API::return_value::success);
char test10_id[16];
::memcpy(test10_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/bzc/d",
"test11", 7);
assert(result == CloudI::API::return_value::success);
char test11_id[16];
::memcpy(test11_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "azb/c/d",
"test12", 7);
assert(result == CloudI::API::return_value::success);
char test12_id[16];
::memcpy(test12_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "a/bzczd",
"test13", 7);
assert(result == CloudI::API::return_value::success);
char test13_id[16];
::memcpy(test13_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "azbzc/d",
"test14", 7);
assert(result == CloudI::API::return_value::success);
char test14_id[16];
::memcpy(test14_id, api.get_trans_id(), 16);
result = api.send_async(std::string(api.prefix()) + "azbzczd",
"test15", 7);
assert(result == CloudI::API::return_value::success);
char test15_id[16];
::memcpy(test15_id, api.get_trans_id(), 16);
// n.b., depends on cloudi_core_i_constants.hrl having
// RECV_ASYNC_STRATEGY == recv_async_select_oldest
result = api.recv_async(test1_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test1_check[6];
assert(api.get_response_size() == 6);
::memcpy(test1_check, api.get_response(), 6);
char test1_id_check[16];
::memcpy(test1_id_check, api.get_trans_id(), 16);
assert(::memcmp(test1_check, "test1", 6) == 0);
assert(::memcmp(test1_id_check, test1_id, 16) == 0);
result = api.recv_async(test2_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test2_check[6];
assert(api.get_response_size() == 6);
::memcpy(test2_check, api.get_response(), 6);
char test2_id_check[16];
::memcpy(test2_id_check, api.get_trans_id(), 16);
assert(::memcmp(test2_check, "test2", 6) == 0);
assert(::memcmp(test2_id_check, test2_id, 16) == 0);
result = api.recv_async(test3_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test3_check[6];
assert(api.get_response_size() == 6);
::memcpy(test3_check, api.get_response(), 6);
char test3_id_check[16];
::memcpy(test3_id_check, api.get_trans_id(), 16);
assert(::memcmp(test3_check, "test3", 6) == 0);
assert(::memcmp(test3_id_check, test3_id, 16) == 0);
result = api.recv_async(test4_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test4_check[6];
assert(api.get_response_size() == 6);
::memcpy(test4_check, api.get_response(), 6);
char test4_id_check[16];
::memcpy(test4_id_check, api.get_trans_id(), 16);
assert(::memcmp(test4_check, "test4", 6) == 0);
assert(::memcmp(test4_id_check, test4_id, 16) == 0);
result = api.recv_async(test5_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test5_check[6];
assert(api.get_response_size() == 6);
::memcpy(test5_check, api.get_response(), 6);
char test5_id_check[16];
::memcpy(test5_id_check, api.get_trans_id(), 16);
assert(::memcmp(test5_check, "test5", 6) == 0);
assert(::memcmp(test5_id_check, test5_id, 16) == 0);
result = api.recv_async(test6_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test6_check[6];
assert(api.get_response_size() == 6);
::memcpy(test6_check, api.get_response(), 6);
char test6_id_check[16];
::memcpy(test6_id_check, api.get_trans_id(), 16);
assert(::memcmp(test6_check, "test6", 6) == 0);
assert(::memcmp(test6_id_check, test6_id, 16) == 0);
result = api.recv_async(test7_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test7_check[6];
assert(api.get_response_size() == 6);
::memcpy(test7_check, api.get_response(), 6);
char test7_id_check[16];
::memcpy(test7_id_check, api.get_trans_id(), 16);
assert(::memcmp(test7_check, "test7", 6) == 0);
assert(::memcmp(test7_id_check, test7_id, 16) == 0);
result = api.recv_async(test8_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test8_check[6];
assert(api.get_response_size() == 6);
::memcpy(test8_check, api.get_response(), 6);
char test8_id_check[16];
::memcpy(test8_id_check, api.get_trans_id(), 16);
assert(::memcmp(test8_check, "test8", 6) == 0);
assert(::memcmp(test8_id_check, test8_id, 16) == 0);
result = api.recv_async(test9_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test9_check[6];
assert(api.get_response_size() == 6);
::memcpy(test9_check, api.get_response(), 6);
char test9_id_check[16];
::memcpy(test9_id_check, api.get_trans_id(), 16);
assert(::memcmp(test9_check, "test9", 6) == 0);
assert(::memcmp(test9_id_check, test9_id, 16) == 0);
result = api.recv_async(test10_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test10_check[7];
assert(api.get_response_size() == 7);
::memcpy(test10_check, api.get_response(), 7);
char test10_id_check[16];
::memcpy(test10_id_check, api.get_trans_id(), 16);
assert(::memcmp(test10_check, "test10", 7) == 0);
assert(::memcmp(test10_id_check, test10_id, 16) == 0);
result = api.recv_async(test11_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test11_check[7];
assert(api.get_response_size() == 7);
::memcpy(test11_check, api.get_response(), 7);
char test11_id_check[16];
::memcpy(test11_id_check, api.get_trans_id(), 16);
assert(::memcmp(test11_check, "test11", 7) == 0);
assert(::memcmp(test11_id_check, test11_id, 16) == 0);
result = api.recv_async(test12_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test12_check[7];
assert(api.get_response_size() == 7);
::memcpy(test12_check, api.get_response(), 7);
char test12_id_check[16];
::memcpy(test12_id_check, api.get_trans_id(), 16);
assert(::memcmp(test12_check, "test12", 7) == 0);
assert(::memcmp(test12_id_check, test12_id, 16) == 0);
result = api.recv_async(test13_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test13_check[7];
assert(api.get_response_size() == 7);
::memcpy(test13_check, api.get_response(), 7);
char test13_id_check[16];
::memcpy(test13_id_check, api.get_trans_id(), 16);
assert(::memcmp(test13_check, "test13", 7) == 0);
assert(::memcmp(test13_id_check, test13_id, 16) == 0);
result = api.recv_async(test14_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test14_check[7];
assert(api.get_response_size() == 7);
::memcpy(test14_check, api.get_response(), 7);
char test14_id_check[16];
::memcpy(test14_id_check, api.get_trans_id(), 16);
assert(::memcmp(test14_check, "test14", 7) == 0);
assert(::memcmp(test14_id_check, test14_id, 16) == 0);
result = api.recv_async(test15_id, false);
assert(result == CloudI::API::return_value::success);
result = api.recv_async();
assert(result == CloudI::API::return_value::success);
char test15_check[7];
assert(api.get_response_size() == 7);
::memcpy(test15_check, api.get_response(), 7);
char test15_id_check[16];
::memcpy(test15_id_check, api.get_trans_id(), 16);
assert(::memcmp(test15_check, "test15", 7) == 0);
assert(::memcmp(test15_id_check, test15_id, 16) == 0);
std::cout << "messaging sequence1 end c++" << std::endl;
// start sequence2
result = api.send_async(std::string(api.prefix()) + "sequence2",
"start", 6);
assert(result == CloudI::API::return_value::success);
api.return_(request_type, name, pattern, "", 0, "end", 4,
timeout, trans_id, pid, pid_size);
}
void sequence2_e1(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "1", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e2(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "2", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e3(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "3", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e4(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "4", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e5(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "5", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e6(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "6", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e7(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "7", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2_e8(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const /*request*/,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
api.return_(request_type, name, pattern, "", 0, "8", 2,
timeout, trans_id, pid, pid_size);
}
void sequence2(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
int result;
std::cout << "messaging sequence2 start c++" << std::endl;
assert(request_size == 6);
assert(::memcmp(request, "start", 6) == 0);
// the sending process is excluded from the services that receive
// the asynchronous message, so in this case, the receiving thread
// will not be called, despite the fact it has subscribed to 'e',
// to prevent a process (in this case thread) from deadlocking
// with itself.
result = api.mcast_async(std::string(api.prefix()) + "e", " ", 2);
assert(result == CloudI::API::return_value::success);
// 4 * 8 == 32, but only 3 out of 4 threads can receive messages,
// since 1 thread is sending the mcast_async, so 3 * 8 == 24
assert(api.get_trans_id_count() == 24);
char e_str_check[25] = " ";
char e_ids[24][16];
::memcpy(reinterpret_cast<char *>(e_ids),
api.get_trans_id(), 24 * 16);
for (unsigned long i = 0; i < 24; ++i)
{
result = api.recv_async(e_ids[i]);
assert(result == CloudI::API::return_value::success);
assert(::memcmp(e_ids[i], api.get_trans_id(), 16) == 0);
assert(api.get_response_size() == 2);
char const integer = api.get_response()[0];
int const index = (integer - '1') * 3;
for (int offset = 0; offset < 3; ++offset)
{
if (e_str_check[index + offset] == ' ')
{
e_str_check[index + offset] = integer;
break;
}
}
}
assert(::memcmp(e_str_check,
"111222333444555666777888999", 24) == 0);
std::cout << "messaging sequence2 end c++" << std::endl;
// start sequence3
result = api.send_async(std::string(api.prefix()) + "sequence3",
"start", 6);
assert(result == CloudI::API::return_value::success);
api.return_(request_type, name, pattern, "", 0, "end", 4,
timeout, trans_id, pid, pid_size);
}
void sequence3_f1(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t priority,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(request_size == 2);
long const request_i =
::strtol(reinterpret_cast<char const *>(request), 0, 10);
assert(request_i >= 0 && request_i <= 4);
if (request_i == 4)
{
api.return_(request_type, name, pattern, "", 0, "done", 5,
timeout, trans_id, pid, pid_size);
assert(false);
return;
}
std::stringstream request_new;
request_new << (request_i + 2);
std::string const & s = request_new.str();
api.forward_(request_type, std::string(api.prefix()) + "f2",
"", 0, s.c_str(), s.size() + 1,
timeout, priority, trans_id, pid, pid_size);
}
void sequence3_f2(CloudI::API const & api,
int const request_type,
std::string const & /*name*/,
std::string const & /*pattern*/,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t priority,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
assert(request_size == 2);
long const request_i =
::strtol(reinterpret_cast<char const *>(request), 0, 10);
assert(request_i >= 2 && request_i <= 5);
std::stringstream request_new;
request_new << (request_i + 2);
std::string const & s = request_new.str();
api.forward_(request_type, std::string(api.prefix()) + "f1",
"", 0, s.c_str(), s.size() + 1,
timeout, priority, trans_id, pid, pid_size);
}
void sequence3_g1(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const /*request_size*/,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
std::string s(reinterpret_cast<char const *>(request));
s += "suffix";
api.return_(request_type, name, pattern,
"", 0, s.c_str(), s.size() + 1,
timeout, trans_id, pid, pid_size);
}
void sequence3(CloudI::API const & api,
int const request_type,
std::string const & name,
std::string const & pattern,
void const * const /*request_info*/,
uint32_t const /*request_info_size*/,
void const * const request,
uint32_t const request_size,
uint32_t timeout,
int8_t /*priority*/,
char const * const trans_id,
char const * const pid,
uint32_t const pid_size)
{
int result;
std::cout << "messaging sequence3 start c++" << std::endl;
assert(request_size == 6);
assert(::memcmp(request, "start", 6) == 0);
result = api.send_async(std::string(api.prefix()) + "f1",
"0", 2);
assert(result == CloudI::API::return_value::success);
char test1_id[16];
::memcpy(test1_id, api.get_trans_id(), 16);
result = api.recv_async(test1_id);
assert(result == CloudI::API::return_value::success);
assert(::memcmp(test1_id, api.get_trans_id(), 16) == 0);
assert(api.get_response_size() == 5);
assert(::memcmp(api.get_response(), "done", 5) == 0);
result = api.send_sync(std::string(api.prefix()) + "g1",
"prefix_", 8);
assert(result == CloudI::API::return_value::success);
assert(api.get_response_size() == 14);
assert(::memcmp(api.get_response(), "prefix_suffix", 14) == 0);
std::cout << "messaging sequence3 end c++" << std::endl;
// loop to find any infrequent problems, restart sequence1
result = api.send_async(std::string(api.prefix()) +
"sequence1", "start", 6);
assert(result == CloudI::API::return_value::success);
api.return_(request_type, name, pattern, "", 0, "end", 4,
timeout, trans_id, pid, pid_size);
}
bool m_stop_default;
bool & m_stop;
CloudI::API m_api;
unsigned int const m_thread_index;
};
class Output
{
public:
Output() : m_got_output(false) {}
void output(OutputData & data)
{
if (data.error() &&
data.error() != CloudI::API::return_value::terminate)
{
std::cerr << "CloudI error " << data.error() << std::endl;
}
m_got_output = true;
}
bool got_output() const { return m_got_output; }
private:
bool m_got_output;
};
int main(int, char **)
{
unsigned int const thread_count = CloudI::API::thread_count();
Output outputObject;
ThreadPool<Input, ThreadData, Output, OutputData>
threadPool(thread_count, thread_count, outputObject);
uint32_t timeout_terminate = 0;
for (unsigned int i = 0; i < thread_count; ++i)
{
Input inputObject(i);
if (timeout_terminate == 0)
{
timeout_terminate = inputObject.timeout_terminate();
assert(timeout_terminate >= 1000);
}
bool const result = threadPool.input(inputObject);
assert(result);
}
while (outputObject.got_output() == false)
::sleep(1);
std::cout << "terminate messaging c++" << std::endl;
threadPool.exit(timeout_terminate - 100);
return 0;
}