Commit 2e4f96ce authored by neverlord's avatar neverlord

bugfix under linux

parent 1bc73535
...@@ -15,7 +15,7 @@ AC_PROG_LIBTOOL ...@@ -15,7 +15,7 @@ AC_PROG_LIBTOOL
# check for C++0x compatibility # check for C++0x compatibility
AC_LANG([C++]) AC_LANG([C++])
ORIGINAL_CPPFLAGS="$CPPFLAGS" ORIGINAL_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -Werror --std=c++0x" CPPFLAGS="$CPPFLAGS -Werror -std=c++0x"
AC_CACHE_CHECK( AC_CACHE_CHECK(
[whether C++ compiler supports variadic templates], [whether C++ compiler supports variadic templates],
...@@ -24,16 +24,15 @@ AC_CACHE_CHECK( ...@@ -24,16 +24,15 @@ AC_CACHE_CHECK(
[ac_cv_cpp_variadic_templates=yes], [ac_cv_cpp_variadic_templates=yes],
[ac_cv_cpp_variadic_templates=no])) [ac_cv_cpp_variadic_templates=no]))
AC_CACHE_CHECK( #AC_CACHE_CHECK(
[whether C++ compiler supports nullptr], # [whether C++ compiler supports nullptr],
[ac_cv_cpp_nullptr], # [ac_cv_cpp_nullptr],
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[static void* myptr = nullptr;]])], # AC_COMPILE_IFELSE([AC_LANG_SOURCE([[static void* myptr = nullptr;]])],
[ac_cv_cpp_nullptr=yes], # [ac_cv_cpp_nullptr=yes],
[ac_cv_cpp_nullptr=no])) # [ac_cv_cpp_nullptr=no]))
AS_IF( AS_IF(
[test "x$ac_cv_cpp_variadic_templates" = "xyes" && [test "x$ac_cv_cpp_variadic_templates" = "xyes" ],
test "x$ac_cv_cpp_nullptr" = "xyes"],
[], [],
[AC_MSG_ERROR([at least one required C++ compiler feature is not supported])]) [AC_MSG_ERROR([at least one required C++ compiler feature is not supported])])
......
...@@ -78,11 +78,11 @@ class any_tuple_view ...@@ -78,11 +78,11 @@ class any_tuple_view
any_tuple_view& operator=(any_tuple_view&&) = default; any_tuple_view& operator=(any_tuple_view&&) = default;
any_tuple_view& operator=(any_tuple_view const&) = default; any_tuple_view& operator=(any_tuple_view const&) = default;
any_tuple_view(any_tuple const& tup) any_tuple_view(any_tuple& tup)
{ {
for (size_t i = 0; i < tup.size(); ++i) for (size_t i = 0; i < tup.size(); ++i)
{ {
m_values.push_back(std::make_pair(tup.type_at(i), tup.at(i))); m_values.push_back(std::make_pair(tup.type_at(i), tup.mutable_at(i)));
} }
} }
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#endif #endif
#ifdef CPPA_DEBUG #ifdef CPPA_DEBUG
#include <cstdio>
#include <cstdlib> #include <cstdlib>
#define CPPA_REQUIRE__(stmt, file, line) \ #define CPPA_REQUIRE__(stmt, file, line) \
printf("%s:%u: requirement failed '%s'\n", file, line, stmt); abort() printf("%s:%u: requirement failed '%s'\n", file, line, stmt); abort()
......
...@@ -329,6 +329,7 @@ bool matches(std::integral_constant<int, 1>, ...@@ -329,6 +329,7 @@ bool matches(std::integral_constant<int, 1>,
Tuple const& tpl, Pattern const& pttrn, Tuple const& tpl, Pattern const& pttrn,
util::fixed_vector<size_t, Pattern::filtered_size>* mv) util::fixed_vector<size_t, Pattern::filtered_size>* mv)
{ {
static_assert(Pattern::size > 0, "empty pattern");
auto end = pttrn.end(); auto end = pttrn.end();
--end; // iterate until we reach "anything" --end; // iterate until we reach "anything"
size_t i = 0; size_t i = 0;
...@@ -351,8 +352,13 @@ bool matches(std::integral_constant<int, 1>, ...@@ -351,8 +352,13 @@ bool matches(std::integral_constant<int, 1>,
if (iter->first != tpl.type_at(i)) return false; if (iter->first != tpl.type_at(i)) return false;
} }
} }
// ok => match // ok => match, fill vector if needed and pattern is != <anything>
if (mv) for (size_t i = 0; i < Pattern::size; ++i) mv->push_back(i); if (mv)
{
// fill vector up to the position of 'anything'
size_t end = Pattern::size - 1;
for (size_t i = 0; i < end; ++i) mv->push_back(i);
}
return true; return true;
} }
...@@ -373,13 +379,13 @@ inline bool matches(Tuple const& tpl, Pattern const& pttrn, ...@@ -373,13 +379,13 @@ inline bool matches(Tuple const& tpl, Pattern const& pttrn,
{ {
typedef typename Pattern::types ptypes; typedef typename Pattern::types ptypes;
static constexpr int first_anything = util::tl_find<ptypes, anything>::value; static constexpr int first_anything = util::tl_find<ptypes, anything>::value;
// impl1 = no anything // impl0 = no anything
// impl2 = anything at end // impl1 = anything at end
// impl3 = anything somewhere in between // impl2 = anything somewhere in between
static constexpr int impl = (first_anything == -1) static constexpr int impl = (first_anything == -1)
? 0 ? 0
: ((first_anything == ((int) Pattern::size) - 1) ? 1 : 2); : ((first_anything == ((int) Pattern::size) - 1) ? 1 : 2);
static constexpr std::integral_constant<int, impl> token; std::integral_constant<int, impl> token;
return matches(token, tpl, pttrn, mv); return matches(token, tpl, pttrn, mv);
} }
......
...@@ -43,7 +43,7 @@ class network_manager ...@@ -43,7 +43,7 @@ class network_manager
virtual ~network_manager(); virtual ~network_manager();
virtual int write_handle() = 0; virtual void write_to_pipe(pipe_msg const& what) = 0;
virtual void start() = 0; virtual void start() = 0;
......
...@@ -61,30 +61,28 @@ class option ...@@ -61,30 +61,28 @@ class option
* @brief Creates an @p option from @p value. * @brief Creates an @p option from @p value.
* @post <tt>valid() == true</tt> * @post <tt>valid() == true</tt>
*/ */
option(T&& value) { cr(std::move(value)); } option(T&& value) : m_valid(false) { cr(std::move(value)); }
/** /**
* @brief Creates an @p option from @p value. * @brief Creates an @p option from @p value.
* @post <tt>valid() == true</tt> * @post <tt>valid() == true</tt>
*/ */
option(T const& value) { cr(value); } option(T const& value) : m_valid(false) { cr(value); }
/** /**
* @brief Copy constructor. * @brief Copy constructor.
*/ */
option(option const& other) option(option const& other) : m_valid(false)
{ {
if (other.m_valid) cr(other.m_value); if (other.m_valid) cr(other.m_value);
else m_valid = false;
} }
/** /**
* @brief Move constructor. * @brief Move constructor.
*/ */
option(option&& other) option(option&& other) : m_valid(false)
{ {
if (other.m_valid) cr(std::move(other.m_value)); if (other.m_valid) cr(std::move(other.m_value));
else m_valid = false;
} }
~option() { destroy(); } ~option() { destroy(); }
...@@ -96,15 +94,8 @@ class option ...@@ -96,15 +94,8 @@ class option
{ {
if (m_valid) if (m_valid)
{ {
if (other.m_valid) if (other.m_valid) m_value = other.m_value;
{ else destroy();
m_value = other.m_value;
}
else
{
destroy();
m_valid = false;
}
} }
else if (other.m_valid) else if (other.m_valid)
{ {
...@@ -120,15 +111,8 @@ class option ...@@ -120,15 +111,8 @@ class option
{ {
if (m_valid) if (m_valid)
{ {
if (other.m_valid) if (other.m_valid) m_value = std::move(other.m_value);
{ else destroy();
m_value = std::move(other.m_value);
}
else
{
destroy();
m_valid = false;
}
} }
else if (other.m_valid) else if (other.m_valid)
{ {
...@@ -234,11 +218,19 @@ class option ...@@ -234,11 +218,19 @@ class option
bool m_valid; bool m_valid;
union { T m_value; }; union { T m_value; };
void destroy() { if (m_valid) m_value.~T(); } void destroy()
{
if (m_valid)
{
m_value.~T();
m_valid = false;
}
}
template<typename V> template<typename V>
void cr(V&& value) void cr(V&& value)
{ {
CPPA_REQUIRE(!valid());
m_valid = true; m_valid = true;
new (&m_value) T (std::forward<V>(value)); new (&m_value) T (std::forward<V>(value));
} }
......
...@@ -71,7 +71,7 @@ template<class ResultTuple, class Tuple, typename... T> ...@@ -71,7 +71,7 @@ template<class ResultTuple, class Tuple, typename... T>
option<ResultTuple> tuple_cast_impl(Tuple const& tup) option<ResultTuple> tuple_cast_impl(Tuple const& tup)
{ {
// no anything in given template parameter pack // no anything in given template parameter pack
if (ResultTuple::num_elements == sizeof...(T)) if (util::tl_find<util::type_list<T...>, anything>::value == -1)
{ {
auto& tarr = detail::static_types_array<T...>::arr; auto& tarr = detail::static_types_array<T...>::arr;
if (tup.size() == sizeof...(T)) if (tup.size() == sizeof...(T))
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
\******************************************************************************/ \******************************************************************************/
#include <iostream>
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/exception.hpp" #include "cppa/exception.hpp"
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <cstdint> #include <cstdint>
#include <cstring> // strerror #include <cstring> // strerror
#include <unistd.h> #include <unistd.h>
#include <iostream>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -73,7 +74,16 @@ struct network_manager_impl : network_manager ...@@ -73,7 +74,16 @@ struct network_manager_impl : network_manager
m_loop = thread(post_office_loop, m_pipe[0], m_pipe[1]); m_loop = thread(post_office_loop, m_pipe[0], m_pipe[1]);
} }
int write_handle() void write_to_pipe(pipe_msg const& what)
{
if (write(m_pipe[1], what, pipe_msg_size) != (int) pipe_msg_size)
{
std::cerr << "FATAL: cannot write to pipe" << std::endl;
abort();
}
}
inline int write_handle() const
{ {
return m_pipe[1]; return m_pipe[1];
} }
...@@ -91,7 +101,7 @@ struct network_manager_impl : network_manager ...@@ -91,7 +101,7 @@ struct network_manager_impl : network_manager
void stop() /*override*/ void stop() /*override*/
{ {
pipe_msg msg = { shutdown_event, 0 }; pipe_msg msg = { shutdown_event, 0 };
write(write_handle(), msg, pipe_msg_size); write_to_pipe(msg);
// m_loop calls close(m_pipe[0]) // m_loop calls close(m_pipe[0])
m_loop.join(); m_loop.join();
close(m_pipe[0]); close(m_pipe[0]);
......
...@@ -497,8 +497,6 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle) ...@@ -497,8 +497,6 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle)
FD_SET(pipe_read_handle, &readset); FD_SET(pipe_read_handle, &readset);
// keeps track about what peer we are iterating at the moment // keeps track about what peer we are iterating at the moment
po_peer* selected_peer = nullptr; po_peer* selected_peer = nullptr;
// our thread id
auto thread_id = this_thread::get_id();
// our event queue // our event queue
auto& msg_queue = singleton_manager::get_network_manager()->post_office_queue(); auto& msg_queue = singleton_manager::get_network_manager()->post_office_queue();
auto pself = process_information::get(); auto pself = process_information::get();
...@@ -526,7 +524,11 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle) ...@@ -526,7 +524,11 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle)
// this callback is not guaranteed to be executed in the same thread // this callback is not guaranteed to be executed in the same thread
msg_queue.push_back(new post_office_msg(pptr_copy)); msg_queue.push_back(new post_office_msg(pptr_copy));
pipe_msg msg = { rd_queue_event, 0 }; pipe_msg msg = { rd_queue_event, 0 };
write(pipe_write_handle, msg, pipe_msg_size); if (write(pipe_write_handle, msg, pipe_msg_size) != (int) pipe_msg_size)
{
cerr << "FATAL: cannot write to pipe" << endl;
abort();
}
}); });
}); });
for (;;) for (;;)
...@@ -565,7 +567,11 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle) ...@@ -565,7 +567,11 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle)
pipe_msg pmsg; pipe_msg pmsg;
//memcpy(pmsg, pipe_msg_buf.data(), pipe_msg_buf.size()); //memcpy(pmsg, pipe_msg_buf.data(), pipe_msg_buf.size());
//pipe_msg_buf.clear(); //pipe_msg_buf.clear();
::read(pipe_read_handle, &pmsg, pipe_msg_size); if (::read(pipe_read_handle, &pmsg, pipe_msg_size) != (int) pipe_msg_size)
{
cerr << "FATAL: cannot read from pipe" << endl;
abort();
}
switch (pmsg[0]) switch (pmsg[0])
{ {
case rd_queue_event: case rd_queue_event:
...@@ -741,7 +747,7 @@ void post_office_add_peer(native_socket_type a0, ...@@ -741,7 +747,7 @@ void post_office_add_peer(native_socket_type a0,
nm->post_office_queue().push_back(new post_office_msg(a0, a1, a2, nm->post_office_queue().push_back(new post_office_msg(a0, a1, a2,
std::move(a3))); std::move(a3)));
pipe_msg msg = { rd_queue_event, 0 }; pipe_msg msg = { rd_queue_event, 0 };
write(nm->write_handle(), msg, pipe_msg_size); nm->write_to_pipe(msg);
} }
void post_office_publish(native_socket_type server_socket, void post_office_publish(native_socket_type server_socket,
...@@ -752,7 +758,7 @@ void post_office_publish(native_socket_type server_socket, ...@@ -752,7 +758,7 @@ void post_office_publish(native_socket_type server_socket,
nm->post_office_queue().push_back(new post_office_msg(server_socket, nm->post_office_queue().push_back(new post_office_msg(server_socket,
published_actor)); published_actor));
pipe_msg msg = { rd_queue_event, 0 }; pipe_msg msg = { rd_queue_event, 0 };
write(nm->write_handle(), msg, pipe_msg_size); nm->write_to_pipe(msg);
} }
void post_office_unpublish(actor_id whom) void post_office_unpublish(actor_id whom)
...@@ -760,14 +766,14 @@ void post_office_unpublish(actor_id whom) ...@@ -760,14 +766,14 @@ void post_office_unpublish(actor_id whom)
DEBUG("post_office_unpublish(" << whom << ")"); DEBUG("post_office_unpublish(" << whom << ")");
auto nm = singleton_manager::get_network_manager(); auto nm = singleton_manager::get_network_manager();
pipe_msg msg = { unpublish_actor_event, whom }; pipe_msg msg = { unpublish_actor_event, whom };
write(nm->write_handle(), msg, pipe_msg_size); nm->write_to_pipe(msg);
} }
void post_office_close_socket(native_socket_type sfd) void post_office_close_socket(native_socket_type sfd)
{ {
auto nm = singleton_manager::get_network_manager(); auto nm = singleton_manager::get_network_manager();
pipe_msg msg = { close_socket_event, static_cast<std::uint32_t>(sfd) }; pipe_msg msg = { close_socket_event, static_cast<std::uint32_t>(sfd) };
write(nm->write_handle(), msg, pipe_msg_size); nm->write_to_pipe(msg);
} }
} } // namespace cppa::detail } } // namespace cppa::detail
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "cppa/detail/thread.hpp" #include "cppa/detail/thread.hpp"
using std::cout; using std::cout;
using std::cerr;
using std::endl; using std::endl;
using namespace cppa; using namespace cppa;
...@@ -62,7 +63,15 @@ size_t test__remote_actor(char const* app_path, bool is_client, ...@@ -62,7 +63,15 @@ size_t test__remote_actor(char const* app_path, bool is_client,
oss << app_path << " run=remote_actor port=" << port;// << " &>/dev/null"; oss << app_path << " run=remote_actor port=" << port;// << " &>/dev/null";
// execute client_part() in a separate process, // execute client_part() in a separate process,
// connected via localhost socket // connected via localhost socket
detail::thread child([&oss]() { system(oss.str().c_str()); }); detail::thread child([&oss]()
{
std::string cmdstr = oss.str();
if (system(cmdstr.c_str()) != 0)
{
cerr << "FATAL: command \"" << cmdstr << "\" failed!" << endl;
abort();
}
});
await_all_others_done(); await_all_others_done();
CPPA_CHECK_EQUAL(pongs(), 5); CPPA_CHECK_EQUAL(pongs(), 5);
// wait until separate process (in sep. thread) finished execution // wait until separate process (in sep. thread) finished execution
......
#define CPPA_VERBOSE_CHECK
#include <list> #include <list>
#include <string> #include <string>
#include <utility> #include <utility>
...@@ -40,7 +42,10 @@ size_t test__tuple() ...@@ -40,7 +42,10 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(t0_0, "1"); CPPA_CHECK_EQUAL(t0_0, "1");
CPPA_CHECK_EQUAL(t0_1, 2); CPPA_CHECK_EQUAL(t0_1, 2);
// get a view of t0 // get a view of t0
auto v1opt = tuple_cast<std::string, anything>(any_tuple_view(t0)); /*
any_tuple atup0(t0);
any_tuple_view aview0(atup0);
auto v1opt = tuple_cast<std::string, anything>(aview0);
CPPA_CHECK((v1opt)); CPPA_CHECK((v1opt));
if (v1opt) if (v1opt)
{ {
...@@ -49,16 +54,19 @@ size_t test__tuple() ...@@ -49,16 +54,19 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(v1.size(), 1); CPPA_CHECK_EQUAL(v1.size(), 1);
CPPA_CHECK_EQUAL(v1_0, "1"); CPPA_CHECK_EQUAL(v1_0, "1");
} }
// */
// use tuple cast to get a subtuple // use tuple cast to get a subtuple
auto v0opt = tuple_cast<std::string, anything>(t0); any_tuple at0(t0);
auto v0opt = tuple_cast<std::string, anything>(at0);
CPPA_CHECK((v0opt)); CPPA_CHECK((v0opt));
if (v0opt) if (v0opt)
{ {
auto& v0 = *v0opt; tuple<std::string>& v0 = *v0opt;
auto v0_0 = get<0>(v0); auto v0_0 = get<0>(v0);
CPPA_CHECK((std::is_same<decltype(v0_0), std::string>::value)); CPPA_CHECK((std::is_same<decltype(v0_0), std::string>::value));
CPPA_CHECK_EQUAL(v0.size(), 1); CPPA_CHECK_EQUAL(v0.size(), 1);
CPPA_CHECK_EQUAL(v0_0, "1"); CPPA_CHECK_EQUAL(v0_0, "1");
CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0));
// check cow semantics // check cow semantics
CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same string CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same string
get_ref<0>(t0) = "hello world"; // detaches t0 from v0 get_ref<0>(t0) = "hello world"; // detaches t0 from v0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment