Commit 2e4f96ce authored by neverlord's avatar neverlord

bugfix under linux

parent 1bc73535
......@@ -15,7 +15,7 @@ AC_PROG_LIBTOOL
# check for C++0x compatibility
AC_LANG([C++])
ORIGINAL_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -Werror --std=c++0x"
CPPFLAGS="$CPPFLAGS -Werror -std=c++0x"
AC_CACHE_CHECK(
[whether C++ compiler supports variadic templates],
......@@ -24,16 +24,15 @@ AC_CACHE_CHECK(
[ac_cv_cpp_variadic_templates=yes],
[ac_cv_cpp_variadic_templates=no]))
AC_CACHE_CHECK(
[whether C++ compiler supports nullptr],
[ac_cv_cpp_nullptr],
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[static void* myptr = nullptr;]])],
[ac_cv_cpp_nullptr=yes],
[ac_cv_cpp_nullptr=no]))
#AC_CACHE_CHECK(
# [whether C++ compiler supports nullptr],
# [ac_cv_cpp_nullptr],
# AC_COMPILE_IFELSE([AC_LANG_SOURCE([[static void* myptr = nullptr;]])],
# [ac_cv_cpp_nullptr=yes],
# [ac_cv_cpp_nullptr=no]))
AS_IF(
[test "x$ac_cv_cpp_variadic_templates" = "xyes" &&
test "x$ac_cv_cpp_nullptr" = "xyes"],
[test "x$ac_cv_cpp_variadic_templates" = "xyes" ],
[],
[AC_MSG_ERROR([at least one required C++ compiler feature is not supported])])
......
......@@ -78,11 +78,11 @@ class any_tuple_view
any_tuple_view& operator=(any_tuple_view&&) = 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)
{
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 @@
#endif
#ifdef CPPA_DEBUG
#include <cstdio>
#include <cstdlib>
#define CPPA_REQUIRE__(stmt, file, line) \
printf("%s:%u: requirement failed '%s'\n", file, line, stmt); abort()
......
......@@ -329,6 +329,7 @@ bool matches(std::integral_constant<int, 1>,
Tuple const& tpl, Pattern const& pttrn,
util::fixed_vector<size_t, Pattern::filtered_size>* mv)
{
static_assert(Pattern::size > 0, "empty pattern");
auto end = pttrn.end();
--end; // iterate until we reach "anything"
size_t i = 0;
......@@ -351,8 +352,13 @@ bool matches(std::integral_constant<int, 1>,
if (iter->first != tpl.type_at(i)) return false;
}
}
// ok => match
if (mv) for (size_t i = 0; i < Pattern::size; ++i) mv->push_back(i);
// ok => match, fill vector if needed and pattern is != <anything>
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;
}
......@@ -373,13 +379,13 @@ inline bool matches(Tuple const& tpl, Pattern const& pttrn,
{
typedef typename Pattern::types ptypes;
static constexpr int first_anything = util::tl_find<ptypes, anything>::value;
// impl1 = no anything
// impl2 = anything at end
// impl3 = anything somewhere in between
// impl0 = no anything
// impl1 = anything at end
// impl2 = anything somewhere in between
static constexpr int impl = (first_anything == -1)
? 0
: ((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);
}
......
......@@ -43,7 +43,7 @@ class network_manager
virtual ~network_manager();
virtual int write_handle() = 0;
virtual void write_to_pipe(pipe_msg const& what) = 0;
virtual void start() = 0;
......
......@@ -61,30 +61,28 @@ class option
* @brief Creates an @p option from @p value.
* @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.
* @post <tt>valid() == true</tt>
*/
option(T const& value) { cr(value); }
option(T const& value) : m_valid(false) { cr(value); }
/**
* @brief Copy constructor.
*/
option(option const& other)
option(option const& other) : m_valid(false)
{
if (other.m_valid) cr(other.m_value);
else m_valid = false;
}
/**
* @brief Move constructor.
*/
option(option&& other)
option(option&& other) : m_valid(false)
{
if (other.m_valid) cr(std::move(other.m_value));
else m_valid = false;
}
~option() { destroy(); }
......@@ -96,15 +94,8 @@ class option
{
if (m_valid)
{
if (other.m_valid)
{
m_value = other.m_value;
}
else
{
destroy();
m_valid = false;
}
if (other.m_valid) m_value = other.m_value;
else destroy();
}
else if (other.m_valid)
{
......@@ -120,15 +111,8 @@ class option
{
if (m_valid)
{
if (other.m_valid)
{
m_value = std::move(other.m_value);
}
else
{
destroy();
m_valid = false;
}
if (other.m_valid) m_value = std::move(other.m_value);
else destroy();
}
else if (other.m_valid)
{
......@@ -234,11 +218,19 @@ class option
bool m_valid;
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>
void cr(V&& value)
{
CPPA_REQUIRE(!valid());
m_valid = true;
new (&m_value) T (std::forward<V>(value));
}
......
......@@ -71,7 +71,7 @@ template<class ResultTuple, class Tuple, typename... T>
option<ResultTuple> tuple_cast_impl(Tuple const& tup)
{
// 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;
if (tup.size() == sizeof...(T))
......
......@@ -28,6 +28,8 @@
\******************************************************************************/
#include <iostream>
#include "cppa/cppa.hpp"
#include "cppa/to_string.hpp"
#include "cppa/exception.hpp"
......
......@@ -33,6 +33,7 @@
#include <cstdint>
#include <cstring> // strerror
#include <unistd.h>
#include <iostream>
#include <sys/time.h>
#include <sys/types.h>
......@@ -73,7 +74,16 @@ struct network_manager_impl : network_manager
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];
}
......@@ -91,7 +101,7 @@ struct network_manager_impl : network_manager
void stop() /*override*/
{
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.join();
close(m_pipe[0]);
......
......@@ -497,8 +497,6 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle)
FD_SET(pipe_read_handle, &readset);
// keeps track about what peer we are iterating at the moment
po_peer* selected_peer = nullptr;
// our thread id
auto thread_id = this_thread::get_id();
// our event queue
auto& msg_queue = singleton_manager::get_network_manager()->post_office_queue();
auto pself = process_information::get();
......@@ -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
msg_queue.push_back(new post_office_msg(pptr_copy));
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 (;;)
......@@ -565,7 +567,11 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle)
pipe_msg pmsg;
//memcpy(pmsg, pipe_msg_buf.data(), pipe_msg_buf.size());
//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])
{
case rd_queue_event:
......@@ -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,
std::move(a3)));
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,
......@@ -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,
published_actor));
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)
......@@ -760,14 +766,14 @@ void post_office_unpublish(actor_id whom)
DEBUG("post_office_unpublish(" << whom << ")");
auto nm = singleton_manager::get_network_manager();
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)
{
auto nm = singleton_manager::get_network_manager();
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
......@@ -9,6 +9,7 @@
#include "cppa/detail/thread.hpp"
using std::cout;
using std::cerr;
using std::endl;
using namespace cppa;
......@@ -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";
// execute client_part() in a separate process,
// 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();
CPPA_CHECK_EQUAL(pongs(), 5);
// wait until separate process (in sep. thread) finished execution
......
#define CPPA_VERBOSE_CHECK
#include <list>
#include <string>
#include <utility>
......@@ -40,7 +42,10 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(t0_0, "1");
CPPA_CHECK_EQUAL(t0_1, 2);
// 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));
if (v1opt)
{
......@@ -49,16 +54,19 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(v1.size(), 1);
CPPA_CHECK_EQUAL(v1_0, "1");
}
// */
// 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));
if (v0opt)
{
auto& v0 = *v0opt;
tuple<std::string>& v0 = *v0opt;
auto v0_0 = get<0>(v0);
CPPA_CHECK((std::is_same<decltype(v0_0), std::string>::value));
CPPA_CHECK_EQUAL(v0.size(), 1);
CPPA_CHECK_EQUAL(v0_0, "1");
CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0));
// check cow semantics
CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same string
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