Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
1122 lines (1072 sloc) 52.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-2020 Michael Truog <mjtruog at protonmail 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 <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/condition_variable.hpp>
#include <iostream>
#include <cstring>
#include <sstream>
#include <limits>
#include "assert.hpp"
class thread_data : public thread_pool_thread_data
{
public:
virtual ~thread_data() throw() {}
};
class task_output_data : public thread_pool_output_data
{
public:
task_output_data(CloudI::API::return_value_type const error) :
m_error(error)
{
}
virtual ~task_output_data() throw() {}
void output_error() const
{
if (m_error && m_error != CloudI::API::return_value::terminate)
std::cerr << "C/C++ CloudI API error " << m_error << std::endl;
}
private:
CloudI::API::return_value_type const m_error;
};
class task : public thread_pool_input<thread_data, task_output_data>
{
public:
task(unsigned int const thread_index,
uint32_t & timeout_terminate) :
m_stop_default(false),
m_stop(m_stop_default),
m_api(thread_index, false),
m_thread_index(thread_index)
{
timeout_terminate = m_api.timeout_terminate();
}
virtual ~task() throw() {}
task_output_data process(bool const & stop, thread_data & /*data*/)
{
int result;
result = m_api.subscribe("a/b/c/d", *this,
&task::sequence1_abcd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/b/c/*", *this,
&task::sequence1_abc_);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/b/*/d", *this,
&task::sequence1_ab_d);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/*/c/d", *this,
&task::sequence1_a_cd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*/b/c/d", *this,
&task::sequence1__bcd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/b/*", *this,
&task::sequence1_ab__);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/*/d", *this,
&task::sequence1_a__d);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*/c/d", *this,
&task::sequence1___cd);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("a/*", *this,
&task::sequence1_a___);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*/d", *this,
&task::sequence1____d);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("*", *this,
&task::sequence1_____);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("sequence1", *this,
&task::sequence1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e2);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e3);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e4);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e5);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e6);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e7);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("e", *this,
&task::sequence2_e8);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("sequence2", *this,
&task::sequence2);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("f1", *this,
&task::sequence3_f1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("f2", *this,
&task::sequence3_f2);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("g1", *this,
&task::sequence3_g1);
assert(result == CloudI::API::return_value::success);
result = m_api.subscribe("sequence3", *this,
&task::sequence3);
assert(result == CloudI::API::return_value::success);
if (m_thread_index == 0)
{
result = m_api.send_async(std::string(m_api.prefix()) +
"sequence1", "1", 2);
assert(result == CloudI::API::return_value::success);
}
m_stop = stop;
while (CloudI::API::return_value::timeout ==
(result = m_api.poll(1000)))
{
if (stop)
{
result = CloudI::API::return_value::success;
break;
}
}
return task_output_data(result);
}
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::string(reinterpret_cast<char const *>(request),
request_size - 1) << ")" << std::endl;
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::string(reinterpret_cast<char const *>(request),
request_size - 1) << ")" << std::endl;
// start sequence2
result = api.send_async(std::string(api.prefix()) + "sequence2",
request, request_size);
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::string(reinterpret_cast<char const *>(request),
request_size - 1) << ")" << std::endl;
// 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::string(reinterpret_cast<char const *>(request),
request_size - 1) << ")" << std::endl;
// start sequence3
result = api.send_async(std::string(api.prefix()) + "sequence3",
request, request_size);
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::string(reinterpret_cast<char const *>(request),
request_size - 1) << ")" << std::endl;
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::string(reinterpret_cast<char const *>(request),
request_size - 1) << ")" << std::endl;
// loop to find any infrequent problems, restart sequence1
long iteration =
::strtol(reinterpret_cast<char const *>(request), 0, 10) + 1;
if (iteration == std::numeric_limits<long>::max())
{
iteration = 0;
}
std::stringstream request_new;
request_new << iteration;
std::string const & s = request_new.str();
result = api.send_async(std::string(api.prefix()) +
"sequence1", s.c_str(), s.size() + 1);
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 task_output : public thread_pool_output<task_output_data>
{
public:
task_output() :
m_terminate(false)
{
}
virtual ~task_output() throw() {}
void output(task_output_data & data)
{
bool terminated;
{
boost::lock_guard<boost::mutex> lock(m_terminate_mutex);
data.output_error();
terminated = m_terminate;
m_terminate = true;
}
if (terminated == false)
m_terminate_conditional.notify_all();
}
void wait_on_terminate()
{
if (m_terminate == false)
{
boost::unique_lock<boost::mutex> lock(m_terminate_mutex);
m_terminate_conditional.wait(lock);
}
}
private:
bool m_terminate;
boost::mutex m_terminate_mutex;
boost::condition_variable m_terminate_conditional;
};
int main(int, char **)
{
try
{
unsigned int const thread_count = CloudI::API::thread_count();
task_output output_object;
thread_pool<task, thread_data, task_output, task_output_data>
thread_pool(thread_count, thread_count, output_object);
uint32_t timeout_terminate = 0;
for (unsigned int i = 0; i < thread_count; ++i)
{
task task_input(i, timeout_terminate);
bool const result = thread_pool.input(task_input);
assert(result);
}
assert(timeout_terminate >= 1000);
output_object.wait_on_terminate();
thread_pool.exit(timeout_terminate - 100);
}
catch (CloudI::API::invalid_input_exception const & e)
{
std::cerr << e.what() << std::endl;
}
catch (CloudI::API::terminate_exception const &)
{
}
std::cout << "terminate messaging c++" << std::endl;
return 0;
}
You can’t perform that action at this time.