Commit c63d96b4 authored by Dominik Charousset's avatar Dominik Charousset

fixed lots of warnings, removed lockfree::queue

this patch fixes lots of warnings about unsafe float comparison,
signess-errors, implicit conversions and handling of enums in
switch statements; furthermore, this patch removes
`boost::lockfree::queue`, mainly because it can hold a maximum
of 2^16 values (which is not accounted for in the implementation
of the scheduler)
parent 278cc01c
......@@ -29,35 +29,6 @@ if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
set(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}")
endif ()
# check if the user provided CXXFLAGS on the command line
if (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED true)
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
else (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED false)
set(CMAKE_CXX_FLAGS "-std=c++11 -Wextra -Wall -pedantic")
if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32")
include (GenerateExportHeader)
endif(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
endif (CMAKE_CXX_FLAGS)
include(CheckIncludeFileCXX)
check_include_file_cxx("valgrind/valgrind.h" HAVE_VALGRIND_H)
if (HAVE_VALGRIND_H)
set(VALGRIND "yes")
add_definitions(-DCPPA_ANNOTATE_VALGRIND)
else (HAVE_VALGRIND_H)
set(VALGRIND "no")
endif (HAVE_VALGRIND_H)
# check for g++ >= 4.7 or clang++ > = 3.2
try_run(ProgramResult
CompilationSucceeded
......@@ -88,6 +59,39 @@ else ()
"or is not supported")
endif ()
# check if the user provided CXXFLAGS on the command line
if (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED true)
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
else (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED false)
if (MORE_CLANG_WARNINGS AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "-std=c++11 -pedantic -Weverything -Wno-c++98-compat -Wno-padded -Wno-documentation-unknown-command -Wno-exit-time-destructors -Wno-global-constructors -Wno-missing-prototypes -Wno-c++98-compat-pedantic -Wno-unused-member-function -Wno-unused-const-variable")
else ()
set(CMAKE_CXX_FLAGS "-std=c++11 -Wextra -Wall -pedantic")
endif ()
if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32")
include (GenerateExportHeader)
endif(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
endif (CMAKE_CXX_FLAGS)
include(CheckIncludeFileCXX)
check_include_file_cxx("valgrind/valgrind.h" HAVE_VALGRIND_H)
if (HAVE_VALGRIND_H)
set(VALGRIND "yes")
add_definitions(-DCPPA_ANNOTATE_VALGRIND)
else (HAVE_VALGRIND_H)
set(VALGRIND "no")
endif (HAVE_VALGRIND_H)
# set build type (evaluate ENABLE_DEBUG flag)
if (ENABLE_DEBUG)
set(CMAKE_BUILD_TYPE Debug)
......@@ -163,6 +167,7 @@ set(LIBCPPA_SRC
src/continue_helper.cpp
src/cs_thread.cpp
src/decorated_tuple.cpp
src/default_message_queue.cpp
src/actor_proxy.cpp
src/peer.cpp
src/peer_acceptor.cpp
......
......@@ -38,6 +38,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--with-opencl build libcppa with OpenCL support
--without-memory-management build libcppa without memory management
--standalone-build build libcppa without Boost or other dependencies
--more-clang-warnings enables most of Clang's warning flags
Installation Directories:
--prefix=PREFIX installation directory [/usr/local]
......@@ -191,6 +192,9 @@ while [ $# -ne 0 ]; do
--standalone-build)
append_cache_entry STANDALONE_BUILD BOOL true
;;
--more-clang-warnings)
append_cache_entry MORE_CLANG_WARNINGS BOOL true
;;
--with-cppa-log-level=*)
level=$(echo "$optarg" | tr '[:lower:]' '[:upper:]')
case $level in
......
......@@ -269,6 +269,7 @@ src/continuable.cpp
src/continue_helper.cpp
src/cs_thread.cpp
src/decorated_tuple.cpp
src/default_message_queue.cpp
src/demangle.cpp
src/deserializer.cpp
src/duration.cpp
......
......@@ -68,6 +68,7 @@
# define CPPA_PUSH_WARNINGS \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wall\"") \
_Pragma("clang diagnostic ignored \"-Wextra\"") \
_Pragma("clang diagnostic ignored \"-Werror\"") \
_Pragma("clang diagnostic ignored \"-Wdeprecated\"") \
_Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \
......@@ -75,6 +76,10 @@
_Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
_Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
_Pragma("clang diagnostic ignored \"-Wswitch-enum\"") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
_Pragma("clang diagnostic ignored \"-Wconversion\"") \
_Pragma("clang diagnostic ignored \"-Wcast-align\"") \
_Pragma("clang diagnostic ignored \"-Wundef\"")
# define CPPA_POP_WARNINGS \
_Pragma("clang diagnostic pop")
......@@ -138,8 +143,8 @@ using ::backtrace_symbols_fd;
printf("%s:%u: requirement failed '%s'\n", file, line, stmt); \
{ \
void* array[10]; \
size_t size = ::cppa::detail::backtrace(array, 10); \
::cppa::detail::backtrace_symbols_fd(array, size, 2); \
auto cppa_bt_size = ::cppa::detail::backtrace(array, 10); \
::cppa::detail::backtrace_symbols_fd(array, cppa_bt_size, 2); \
} \
abort()
# define CPPA_REQUIRE(stmt) \
......
......@@ -44,6 +44,8 @@ class container_tuple_view : public abstract_tuple {
typedef abstract_tuple super;
typedef typename Container::difference_type difference_type;
public:
typedef typename Container::value_type value_type;
......@@ -54,33 +56,35 @@ class container_tuple_view : public abstract_tuple {
if (!take_ownership) m_ptr.get_deleter().disable();
}
size_t size() const {
size_t size() const override {
return m_ptr->size();
}
abstract_tuple* copy() const {
abstract_tuple* copy() const override {
return new container_tuple_view{new Container(*m_ptr), true};
}
const void* at(size_t pos) const {
const void* at(size_t pos) const override {
CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(static_cast<difference_type>(pos) >= 0);
auto i = m_ptr->cbegin();
std::advance(i, pos);
std::advance(i, static_cast<difference_type>(pos));
return &(*i);
}
void* mutable_at(size_t pos) {
void* mutable_at(size_t pos) override {
CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(static_cast<difference_type>(pos) >= 0);
auto i = m_ptr->begin();
std::advance(i, pos);
std::advance(i, static_cast<difference_type>(pos));
return &(*i);
}
const uniform_type_info* type_at(size_t) const {
const uniform_type_info* type_at(size_t) const override {
return static_types_array<value_type>::arr[0];
}
const std::string* tuple_type_names() const {
const std::string* tuple_type_names() const override {
static std::string result = demangle<value_type>();
return &result;
}
......
......@@ -34,6 +34,8 @@
#include <type_traits>
#include "cppa/unit.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
......@@ -60,7 +62,7 @@ template<typename T>
struct vg_cmp {
template<typename U>
inline static bool _(const T& lhs, const U& rhs) {
return lhs == rhs;
return util::safe_equal(lhs, rhs);
}
};
......
......@@ -42,6 +42,7 @@
#include "cppa/optional.hpp"
#include "cppa/util/call.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/util/rebindable_reference.hpp"
......@@ -101,13 +102,15 @@ struct guard_expr {
};
#define CPPA_FORALL_OPS(SubMacro) \
/*
* @brief Invokes SubMacro for "+", "-", "*", "/", "%", "<", "<=", ">" and ">=".
**/
#define CPPA_FORALL_DEFAULT_OPS(SubMacro) \
SubMacro (addition_op, +) SubMacro (subtraction_op, -) \
SubMacro (multiplication_op, *) SubMacro (division_op, /) \
SubMacro (modulo_op, %) SubMacro (less_op, <) \
SubMacro (less_eq_op, <=) SubMacro (greater_op, >) \
SubMacro (greater_eq_op, >=) SubMacro (equal_op, ==) \
SubMacro (not_equal_op, !=)
SubMacro (greater_eq_op, >=)
/**
* @brief Creates a reference wrapper similar to std::reference_wrapper<const T>
......@@ -418,7 +421,9 @@ ge_concatenate(T1 first, T2 second,
return ge_concatenate< EnumValue >(v1, v2); \
}
CPPA_FORALL_OPS(CPPA_GE_OPERATOR)
CPPA_FORALL_DEFAULT_OPS(CPPA_GE_OPERATOR)
CPPA_GE_OPERATOR(equal_op, ==)
CPPA_GE_OPERATOR(not_equal_op, !=)
template<operator_id OP>
struct ge_eval_op;
......@@ -430,10 +435,25 @@ struct ge_eval_op;
-> decltype(lhs Operator rhs) { return lhs Operator rhs; } \
};
CPPA_FORALL_OPS(CPPA_EVAL_OP_IMPL)
CPPA_FORALL_DEFAULT_OPS(CPPA_EVAL_OP_IMPL)
CPPA_EVAL_OP_IMPL(logical_and_op, &&)
CPPA_EVAL_OP_IMPL(logical_or_op, ||)
template<> struct ge_eval_op<equal_op> {
template<typename T1, typename T2>
static inline bool _(const T1& lhs, const T2& rhs) {
return util::safe_equal(lhs, rhs);
}
};
template<> struct ge_eval_op<not_equal_op> {
template<typename T1, typename T2>
static inline bool _(const T1& lhs, const T2& rhs) {
return !util::safe_equal(lhs, rhs);
}
};
template<typename T, class Tuple>
struct ge_result_ {
typedef typename ge_unbound<T, Tuple>::type type;
......
......@@ -81,6 +81,8 @@ class blocking_single_reader_queue {
// actor no longer alive
return false;
}
// should be unreachable
CPPA_CRITICAL("invalid result of enqueue()");
}
inline void clear() {
......
......@@ -42,7 +42,7 @@ namespace cppa { namespace intrusive {
enum enqueue_result { enqueued, first_enqueued, queue_closed };
/**
* @brief An intrusive, thread safe queue implementation.
* @brief An intrusive, thread-safe queue implementation.
* @note For implementation details see
* http://libcppa.blogspot.com/2011/04/mailbox-part-1.html
*/
......
......@@ -31,6 +31,8 @@
#ifndef CPPA_MESSAGE_QUEUE_HPP
#define CPPA_MESSAGE_QUEUE_HPP
#include <vector>
#include "cppa/any_tuple.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/message_header.hpp"
......@@ -45,6 +47,8 @@ class default_message_queue : public ref_counted {
typedef value_type& reference;
~default_message_queue();
template<typename... Ts>
void emplace(Ts&&... args) {
m_impl.emplace_back(std::forward<Ts>(args)...);
......
......@@ -105,7 +105,16 @@ class context_switching_resume {
// wait until someone re-schedules that actor
return resumable::resume_later;
}
default: { CPPA_CRITICAL("illegal yield result"); }
case actor_state::about_to_block:
CPPA_CRITICAL("attempt to set state from "
"about_to_block to blocked "
"failed: state is still set "
"to about_to_block");
case actor_state::done:
CPPA_CRITICAL("attempt to set state from "
"about_to_block to blocked "
"failed: state is set "
"to done");
}
break;
}
......
......@@ -371,6 +371,8 @@ class invoke_policy {
return hm_cache_msg;
}
}
// should be unreachable
CPPA_CRITICAL("invalid message type");
}
Derived* dptr() {
......
......@@ -52,8 +52,8 @@ class actor_widget_mixin : public Base {
message_pointer mptr;
event_type(message_pointer mptr)
: QEvent(static_cast<QEvent::Type>(EventId)), mptr(std::move(mptr)) { }
event_type(message_pointer ptr)
: QEvent(static_cast<QEvent::Type>(EventId)), mptr(std::move(ptr)) { }
};
......
......@@ -31,8 +31,10 @@
#ifndef CPPA_UTIL_SPLIT_HPP
#define CPPA_UTIL_SPLIT_HPP
#include <cmath> // fabs
#include <string>
#include <vector>
#include <limits>
#include <sstream>
#include <algorithm>
#include <type_traits>
......@@ -74,6 +76,31 @@ void splice(std::string& str, const std::string& glue, T&& arg, Ts&&... args) {
splice(str, glue, std::forward<Ts>(args)...);
}
/**
* @brief Compares two values by using @p operator== unless two floating
* point numbers are compared. In the latter case, the function
* performs an epsilon comparison.
*/
template<typename T, typename U>
typename std::enable_if<
!std::is_floating_point<T>::value && !std::is_floating_point<U>::value,
bool
>::type
safe_equal(const T& lhs, const U& rhs) {
return lhs == rhs;
}
template<typename T, typename U>
typename std::enable_if<
std::is_floating_point<T>::value || std::is_floating_point<U>::value,
bool
>::type
safe_equal(const T& lhs, const U& rhs) {
typedef decltype(lhs - rhs) res_type;
return std::fabs(lhs - rhs) <= std::numeric_limits<res_type>::epsilon();
}
} } // namespace cppa::util
#endif // CPPA_UTIL_SPLIT_HPP
......@@ -33,6 +33,7 @@
#include "cppa/get.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
......@@ -47,7 +48,7 @@ do_get(const Tuple<Ts...>& t) {
template<size_t N, typename LhsTuple, typename RhsTuple>
struct cmp_helper {
inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs) {
return do_get<N>(lhs) == do_get<N>(rhs)
return util::safe_equal(do_get<N>(lhs), do_get<N>(rhs))
&& cmp_helper<N-1, LhsTuple, RhsTuple>::cmp(lhs, rhs);
}
};
......
......@@ -34,6 +34,7 @@
#include <string>
#include <chrono>
#include <cstdint>
#include <stdexcept>
namespace cppa { namespace util {
......
......@@ -108,7 +108,9 @@ class limited_vector {
void assign(InputIterator first, InputIterator last,
// dummy SFINAE argument
typename std::iterator_traits<InputIterator>::pointer = 0) {
resize(std::distance(first, last));
auto dist = std::distance(first, last);
CPPA_REQUIRE(dist >= 0);
resize(static_cast<size_t>(dist));
std::copy(first, last, begin());
}
......@@ -247,7 +249,8 @@ class limited_vector {
*/
template<class InputIterator>
inline void insert(iterator pos, InputIterator first, InputIterator last) {
auto num_elements = std::distance(first, last);
CPPA_REQUIRE(first <= last);
auto num_elements = static_cast<size_t>(std::distance(first, last));
if ((size() + num_elements) > MaxSize) {
throw std::length_error("limited_vector::insert: too much elements");
}
......
......@@ -33,44 +33,6 @@
#include "cppa/config.hpp"
#ifndef CPPA_STANDALONE_BUILD
CPPA_PUSH_WARNINGS
#include <boost/lockfree/queue.hpp>
CPPA_POP_WARNINGS
namespace cppa {
namespace util {
template<typename T>
class producer_consumer_list {
public:
inline T* try_pop() {
T* res;
return m_queue.pop(res) ? res : nullptr;
}
inline void push_back(T* ptr) {
m_queue.push(ptr);
}
inline bool empty() {
return m_queue.empty();
}
private:
boost::lockfree::queue<T*> m_queue;
};
} // namespace util
} // namespace cppa
#else // fallback implementation in case Boost is not available
#define CPPA_CACHE_LINE_SIZE 64
#include <chrono>
......@@ -239,6 +201,4 @@ class producer_consumer_list {
} } // namespace cppa::util
#endif // CPPA_STANDALONE_BUILD
#endif // CPPA_PRODUCER_CONSUMER_LIST_HPP
......@@ -11,7 +11,7 @@ using namespace cppa;
using std::endl;
int main() {
std::srand(std::time(0));
std::srand(static_cast<unsigned>(std::time(0)));
for (int i = 1; i <= 50; ++i) {
spawn<blocking_api>([i](blocking_actor* self) {
aout(self) << "Hi there! This is actor nr. "
......
......@@ -74,9 +74,17 @@
// libcppa
#include "cppa/cppa.hpp"
// disable some clang warnings here caused by CURL and srand(time(nullptr))
#ifdef __clang__
# pragma clang diagnostic ignored "-Wshorten-64-to-32"
# pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#endif // __clang__
using namespace cppa;
namespace color { namespace {
namespace {
namespace color {
// UNIX terminal color codes
constexpr char reset[] = "\033[0m";
......@@ -98,9 +106,7 @@ constexpr char bold_magenta[] = "\033[1m\033[35m";
constexpr char bold_cyan[] = "\033[1m\033[36m";
constexpr char bold_white[] = "\033[1m\033[37m";
} } // namespace color::<anonymous>
namespace {
} // namespace color
// number of HTTP workers
constexpr size_t num_curl_workers = 10;
......@@ -109,8 +115,6 @@ constexpr size_t num_curl_workers = 10;
constexpr int min_req_interval = 10;
constexpr int max_req_interval = 300;
} // namespace <anonymous>
// provides print utility and each base_actor has a parent
class base_actor : public event_based_actor {
......@@ -369,7 +373,9 @@ class curl_master : public base_actor {
};
// signal handling for ctrl+c
namespace { std::atomic<bool> shutdown_flag{false}; }
std::atomic<bool> shutdown_flag{false};
} // namespace <anonymous>
int main() {
// random number setup
......
......@@ -16,6 +16,8 @@ using std::chrono::seconds;
using namespace std;
using namespace cppa;
namespace {
// either taken by a philosopher or available
void chopstick(event_based_actor* self) {
self->become(
......@@ -186,6 +188,8 @@ void dining_philosophers() {
}
}
} // namespace <anonymous>
int main(int, char**) {
dining_philosophers();
// real philosophers are never done
......
......@@ -10,6 +10,8 @@
using std::endl;
using namespace cppa;
namespace {
struct shutdown_request { };
struct plus_request { int a; int b; };
struct minus_request { int a; int b; };
......@@ -77,6 +79,8 @@ void tester(event_based_actor* self, const calculator_type& testee) {
);
}
} // namespace <anonymous>
int main() {
// announce custom message types
announce<shutdown_request>();
......
......@@ -114,7 +114,6 @@ void ChatWidget::joinGroup() {
}
string mod = gname.left(pos).toUtf8().constData();
string gid = gname.midRef(pos+1).toUtf8().constData();
group gptr;
try {
auto gptr = group::get(mod, gid);
send_as(as_actor(), as_actor(), atom("join"), gptr);
......
......@@ -29,6 +29,9 @@ using namespace std;
using namespace cppa;
using namespace cppa::placeholders;
/*
namespace {
struct line { string str; };
istream& operator>>(istream& is, line& l) {
......@@ -49,6 +52,9 @@ any_tuple split_line(const line& l) {
return s_last_line;
}
} // namespace <anonymous>
*/
int main(int argc, char** argv) {
string name;
......@@ -97,7 +103,8 @@ int main(int argc, char** argv) {
send_as(client, client, atom("join"), gptr);
}
mw.show();
return app.exec();
auto res = app.exec();
shutdown();
return 0;
await_all_actors_done();
return res;
}
......@@ -88,10 +88,10 @@ void client_bhvr(event_based_actor* self, const string& host, uint16_t port, con
aout(self) << "*** server down, try to reconnect ..." << endl;
client_bhvr(self, host, port, invalid_actor);
},
on(atom("rebind"), arg_match) >> [=](const string& host, uint16_t port) {
on(atom("rebind"), arg_match) >> [=](const string& nhost, uint16_t nport) {
aout(self) << "*** rebind to new server: "
<< host << ":" << port << endl;
client_bhvr(self, host, port, invalid_actor);
<< nhost << ":" << nport << endl;
client_bhvr(self, nhost, nport, invalid_actor);
},
on(atom("reconnect")) >> [=] {
client_bhvr(self, host, port, invalid_actor);
......@@ -120,18 +120,18 @@ void client_repl(const string& host, uint16_t port) {
// the STL way of line.starts_with("connect")
else if (equal(begin(connect), end(connect) - 1, begin(line))) {
match_split(line, ' ') (
on("connect", arg_match) >> [&](string& host, string& sport) {
on("connect", arg_match) >> [&](string& nhost, string& sport) {
try {
auto lport = std::stoul(sport);
if (lport < std::numeric_limits<uint16_t>::max()) {
auto port = static_cast<uint16_t>(lport);
anon_send(client, atom("rebind"), move(host), port);
anon_send(client, atom("rebind"), move(nhost),
static_cast<uint16_t>(lport));
}
else {
cout << lport << " is not a valid port" << endl;
}
}
catch (std::exception& e) {
catch (std::exception&) {
cout << "\"" << sport << "\" is not an unsigned integer"
<< endl;
}
......
......@@ -20,6 +20,8 @@ using std::endl;
using namespace cppa;
namespace {
// a node containing an integer and a vector of children
struct tree_node {
std::uint32_t value;
......@@ -164,6 +166,8 @@ void testee(event_based_actor* self, size_t remaining) {
);
}
} // namespace <anonymous>
int main() {
// the tree_type_info is owned by libcppa after this function call
announce(typeid(tree), std::unique_ptr<uniform_type_info>{new tree_type_info});
......
......@@ -70,6 +70,7 @@ const std::string& abstract_group::module_name() const {
return get_module()->name();
}
namespace {
struct group_nameserver : event_based_actor {
behavior make_behavior() override {
return (
......@@ -81,11 +82,8 @@ struct group_nameserver : event_based_actor {
}
);
}
~group_nameserver();
};
// avoid weak-vtables warning by providing dtor out-of-line
group_nameserver::~group_nameserver() { }
} // namespace <anonymous>
void publish_local_groups(std::uint16_t port, const char* addr) {
auto gn = spawn<group_nameserver, hidden>();
......
......@@ -33,6 +33,7 @@
namespace cppa {
namespace {
class continuation_decorator : public detail::behavior_impl {
typedef behavior_impl super;
......@@ -43,8 +44,6 @@ class continuation_decorator : public detail::behavior_impl {
typedef typename behavior_impl::pointer pointer;
~continuation_decorator();
continuation_decorator(continuation_fun fun, pointer ptr)
: super(ptr->timeout()), m_fun(fun), m_decorated(std::move(ptr)) {
CPPA_REQUIRE(m_decorated != nullptr);
......@@ -81,9 +80,7 @@ class continuation_decorator : public detail::behavior_impl {
pointer m_decorated;
};
// avoid weak-vtables warning by providing dtor out-of-line
continuation_decorator::~continuation_decorator() { }
} // namespace <anonymous>
behavior::behavior(const partial_function& fun) : m_impl(fun.m_impl) { }
......
......@@ -184,8 +184,6 @@ namespace {
// base class for cs_thread pimpls
struct cst_impl {
cst_impl() : m_ctx() { }
virtual ~cst_impl();
virtual void run() = 0;
......@@ -198,14 +196,13 @@ struct cst_impl {
};
// avoid weak-vtables warning by providing dtor out-of-line
cst_impl::~cst_impl() { }
namespace {
// a cs_thread representing a thread ('converts' the thread to a cs_thread)
struct converted_cs_thread : cst_impl {
~converted_cs_thread();
converted_cs_thread() {
init_converted_context(m_converted, m_ctx);
}
......@@ -218,9 +215,6 @@ struct converted_cs_thread : cst_impl {
};
// avoid weak-vtables warning by providing dtor out-of-line
converted_cs_thread::~converted_cs_thread() { }
// a cs_thread executing a function
struct fun_cs_thread : cst_impl {
......@@ -228,7 +222,9 @@ struct fun_cs_thread : cst_impl {
m_stack_info = new_stack(m_ctx, m_alloc, m_vgm);
}
~fun_cs_thread();
~fun_cs_thread() {
del_stack(m_alloc, m_stack_info, m_vgm);
}
void run() override {
m_fun(m_arg);
......@@ -242,10 +238,7 @@ struct fun_cs_thread : cst_impl {
};
// avoid weak-vtables warning by providing dtor out-of-line
fun_cs_thread::~fun_cs_thread() {
del_stack(m_alloc, m_stack_info, m_vgm);
}
} // namespace <anonymous>
void cst_trampoline(intptr_t iptr) {
auto ptr = (cst_impl*) iptr;
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include "cppa/io/default_message_queue.hpp"
namespace cppa {
namespace io {
default_message_queue::~default_message_queue() { }
} // namespace io
} // namespace cppa
......@@ -151,7 +151,9 @@ io::stream_ptr ipv4_io_stream::connect_to(const char* host,
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memmove(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
memmove(&serv_addr.sin_addr.s_addr,
server->h_addr,
static_cast<size_t>(server->h_length));
serv_addr.sin_port = htons(port);
CPPA_LOGF_DEBUG("call connect()");
if (connect(fd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) {
......
......@@ -430,18 +430,24 @@ void middleman_loop(middleman_impl* impl) {
handler->poll([&](event_bitmask mask, continuable* io) {
switch (mask) {
default: CPPA_CRITICAL("invalid event");
case event::none: break;
case event::none:
// should not happen
CPPA_LOGF_WARNING("polled an event::none event");
break;
case event::both:
case event::write: {
case event::write:
CPPA_LOGF_DEBUG("handle event::write for " << io);
switch (io->continue_writing()) {
case continue_writing_result::failure:
io->io_failed(event::write);
CPPA_ANNOTATE_FALLTHROUGH;
impl->stop_writer(io);
CPPA_LOGF_DEBUG("writer removed because "
"of an error");
break;
case continue_writing_result::closed:
impl->stop_writer(io);
CPPA_LOGF_DEBUG("writer removed because "
"of error write_closed or ");
"connection has been closed");
break;
case continue_writing_result::done:
impl->stop_writer(io);
......@@ -454,16 +460,19 @@ void middleman_loop(middleman_impl* impl) {
// else: fall through
CPPA_LOGF_DEBUG("handle event::both; fall through");
CPPA_ANNOTATE_FALLTHROUGH;
}
case event::read: {
CPPA_LOGF_DEBUG("handle event::read for " << io);
switch (io->continue_reading()) {
case continue_reading_result::failure:
io->io_failed(event::read);
CPPA_ANNOTATE_FALLTHROUGH;
impl->stop_reader(io);
CPPA_LOGF_DEBUG("peer removed because a "
"read error has occured");
break;
case continue_reading_result::closed:
impl->stop_reader(io);
CPPA_LOGF_DEBUG("remove peer");
CPPA_LOGF_DEBUG("peer removed because "
"connection has been closed");
break;
case continue_reading_result::continue_later:
// nothing to do
......
......@@ -78,7 +78,7 @@ void host_id_from_string(const std::string& hash,
for (size_t i = 0; i < node_id.size(); ++i) {
// read two characters, each representing 4 bytes
auto& val = node_id[i];
val = hex_char_value(*j++) << 4;
val = static_cast<uint8_t>(hex_char_value(*j++) << 4);
val |= hex_char_value(*j++);
}
}
......@@ -93,7 +93,7 @@ bool equal(const std::string& hash,
for (size_t i = 0; i < node_id.size(); ++i) {
// read two characters, each representing 4 bytes
std::uint8_t val;
val = hex_char_value(*j++) << 4;
val = static_cast<uint8_t>(hex_char_value(*j++) << 4);
val |= hex_char_value(*j++);
if (val != node_id[i]) {
return false;
......
......@@ -31,6 +31,9 @@
#include <typeinfo>
#include "cppa/primitive_variant.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/detail/type_to_ptype.hpp"
namespace cppa {
......@@ -77,7 +80,8 @@ struct comparator {
template<primitive_type PT>
void operator()(util::pt_token<PT>) {
if (rhs.ptype() == PT) {
result = (get<PT>(lhs) == get<PT>(rhs));
result = util::safe_equal(get<PT>(lhs), get<PT>(rhs));
//result = (get<PT>(lhs) == get<PT>(rhs));
}
}
};
......
......@@ -211,6 +211,8 @@ class string_deserializer : public deserializer {
typedef deserializer super;
typedef string::iterator::difference_type difference_type;
string m_str;
string::iterator m_pos;
//size_t m_obj_count;
......@@ -338,7 +340,8 @@ class string_deserializer : public deserializer {
size_t begin_sequence() {
integrity_check();
consume('{');
return count(m_pos, find(m_pos, m_str.end(), '}'), ',') + 1;
auto num_vals = count(m_pos, find(m_pos, m_str.end(), '}'), ',') + 1;
return static_cast<size_t>(num_vals);
}
void end_sequence() {
......@@ -415,7 +418,7 @@ class string_deserializer : public deserializer {
throw logic_error("malformed string (unterminated value)");
}
string substr(m_pos, substr_end);
m_pos += substr.size();
m_pos += static_cast<difference_type>(substr.size());
if (ptype == pt_u8string || ptype == pt_atom) {
char needle = (ptype == pt_u8string) ? '"' : '\'';
// skip trailing "
......
......@@ -29,6 +29,7 @@
#include <array>
#include <limits>
#include <string>
#include <vector>
#include <cstring>
......@@ -452,7 +453,9 @@ class uti_base : public uniform_type_info {
}
bool equals(const void* lhs, const void* rhs) const override {
return deref(lhs) == deref(rhs);
//return util::safe_equal(deref(lhs), deref(rhs));
//return deref(lhs) == deref(rhs);
return eq(deref(lhs), deref(rhs));
}
void* new_instance(const void* ptr) const override {
......@@ -477,6 +480,20 @@ class uti_base : public uniform_type_info {
const std::type_info* m_native;
private:
template<typename U>
typename std::enable_if<std::is_floating_point<U>::value, bool>::type
eq(const U& lhs, const U& rhs) const {
return util::safe_equal(lhs, rhs);
}
template<typename U>
typename std::enable_if<!std::is_floating_point<U>::value, bool>::type
eq(const U& lhs, const U& rhs) const {
return lhs == rhs;
}
};
template<typename T>
......@@ -890,7 +907,7 @@ class utim_impl : public uniform_type_info_map {
// insert after lower bound (vector is always sorted)
auto new_pos = std::distance(m_user_types.begin(), i);
m_user_types.insert(i, uti.release());
return m_user_types[new_pos];
return m_user_types[static_cast<size_t>(new_pos)];
}
}
......
......@@ -52,7 +52,7 @@ vector<string> split(const string& str, char delim, bool keep_empties) {
return result;
}
void verbose_terminate() {
void verbose_terminate [[noreturn]] () {
try { throw; }
catch (exception& e) {
CPPA_PRINTERR("terminate called after throwing "
......
......@@ -106,7 +106,7 @@ inline void cppa_check_value(const V1& v1,
size_t line,
bool expected = true,
typename enable_integral<false, V1, V2>::type* = 0) {
if ((v1 == v2) == expected) cppa_passed(fname, line);
if (cppa::util::safe_equal(v1, v2) == expected) cppa_passed(fname, line);
else cppa_failed(v1, v2, fname, line);
}
......
......@@ -12,8 +12,6 @@ namespace {
int class0_instances = 0;
int class1_instances = 0;
}
struct class0 : ref_counted {
class0() { ++class0_instances; }
......@@ -41,6 +39,8 @@ class0_ptr get_test_ptr() {
return get_test_rc();
}
} // namespace <anonymous>
int main() {
// this test dosn't test thread-safety of intrusive_ptr
// however, it is thread safe since it uses atomic operations only
......
......@@ -168,7 +168,8 @@ void test_gref() {
on<anything>() >> [] { return 2; }
);
any_tuple expr19_tup = make_cow_tuple("hello guard!");
CPPA_CHECK_EQUAL(expr19(expr19_tup), 2);
auto res19 = expr19(expr19_tup);
CPPA_CHECK(res19.is<int>() && get<int>(res19) == 2);
partial_function expr20 = expr19;
enable_case1 = false;
CPPA_CHECK(expr20(expr19_tup) == make_any_tuple(1));
......@@ -219,7 +220,7 @@ void test_match_function() {
return "C";
}
);
CPPA_CHECK_EQUAL(res5, "C");
CPPA_CHECK_EQUAL(get<string>(res5), "C");
}
void test_match_each() {
......@@ -341,7 +342,7 @@ void test_pattern_matching() {
return f;
}
);
CPPA_CHECK(res && res.is<float>() && get<float>(res) == 4.2f);
CPPA_CHECK(res && res.is<float>() && util::safe_equal(get<float>(res), 4.2f));
auto res2 = match(make_any_tuple(23, 4.2f)) (
on(42, arg_match) >> [](double d) {
return d;
......
......@@ -137,8 +137,6 @@ void spawn5_client(event_based_actor* self) {
);
}
} // namespace <anonymous>
template<typename F>
void await_down(event_based_actor* self, actor ptr, F continuation) {
self->become (
......@@ -324,6 +322,8 @@ class server : public event_based_actor {
};
} // namespace <anonymous>
int main(int argc, char** argv) {
announce<actor_vector>();
announce_tuple<atom_value, int>();
......
......@@ -59,37 +59,19 @@ using namespace cppa::util;
using cppa::detail::type_to_ptype;
using cppa::detail::ptype_to_type;
namespace {
struct struct_a {
int x;
int y;
};
bool operator==(const struct_a& lhs, const struct_a& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
bool operator!=(const struct_a& lhs, const struct_a& rhs) {
return !(lhs == rhs);
}
struct struct_b {
struct_a a;
int z;
list<int> ints;
};
string to_string(const struct_b& what) {
return to_string(object::from(what));
}
bool operator==(const struct_b& lhs, const struct_b& rhs) {
return lhs.a == rhs.a && lhs.z == rhs.z && lhs.ints == rhs.ints;
}
bool operator!=(const struct_b& lhs, const struct_b& rhs) {
return !(lhs == rhs);
}
typedef map<string, u16string> strmap;
struct struct_c {
......@@ -97,14 +79,6 @@ struct struct_c {
set<int> ints;
};
bool operator==(const struct_c& lhs, const struct_c& rhs) {
return lhs.strings == rhs.strings && lhs.ints == rhs.ints;
}
bool operator!=(const struct_c& lhs, const struct_c& rhs) {
return !(lhs == rhs);
}
struct raw_struct {
string str;
};
......@@ -113,10 +87,6 @@ bool operator==(const raw_struct& lhs, const raw_struct& rhs) {
return lhs.str == rhs.str;
}
bool operator!=(const raw_struct& lhs, const raw_struct& rhs) {
return lhs.str != rhs.str;
}
struct raw_struct_type_info : util::abstract_uniform_type_info<raw_struct> {
void serialize(const void* ptr, serializer* sink) const override {
auto rs = reinterpret_cast<const raw_struct*>(ptr);
......@@ -150,6 +120,8 @@ void test_ieee_754() {
CPPA_CHECK_EQUAL(f2, u2);
}
} // namespace <anonymous>
int main() {
CPPA_TEST(test_serialization);
......
......@@ -11,6 +11,8 @@
using namespace std;
using namespace cppa;
namespace {
class event_testee : public sb_actor<event_testee> {
friend class sb_actor<event_testee>;
......@@ -58,7 +60,7 @@ class event_testee : public sb_actor<event_testee> {
actor spawn_event_testee2(actor parent) {
struct impl : event_based_actor {
actor parent;
impl(actor parent) : parent(parent) { }
impl(actor parent_actor) : parent(parent_actor) { }
behavior wait4timeout(int remaining) {
CPPA_LOG_TRACE(CPPA_ARG(remaining));
return {
......@@ -328,7 +330,7 @@ struct master : event_based_actor {
struct slave : event_based_actor {
slave(actor master) : master{master} { }
slave(actor master_actor) : master{master_actor} { }
behavior make_behavior() override {
link_to(master);
......@@ -477,7 +479,6 @@ void test_continuation() {
}
void test_simple_reply_response() {
scoped_actor self;
auto s = spawn([](event_based_actor* self) -> behavior {
return (
others() >> [=]() -> any_tuple {
......@@ -487,6 +488,7 @@ void test_simple_reply_response() {
}
);
});
scoped_actor self;
self->send(s, atom("hello"));
self->receive(
others() >> [&] {
......@@ -630,7 +632,7 @@ void test_spawn() {
self->await_all_other_actors_done();
CPPA_CHECKPOINT();
auto st = spawn<fixed_stack>(10);
auto st = spawn<fixed_stack>(size_t{10});
// push 20 values
for (int i = 0; i < 20; ++i) self->send(st, atom("push"), i);
// pop 20 times
......@@ -660,8 +662,8 @@ void test_spawn() {
self->await_all_other_actors_done();
CPPA_CHECKPOINT();
auto sync_testee1 = spawn<blocking_api>([](blocking_actor* self) {
self->receive (
auto sync_testee1 = spawn<blocking_api>([](blocking_actor* s) {
s->receive (
on(atom("get")) >> [] {
return make_cow_tuple(42, 2);
}
......@@ -701,12 +703,12 @@ void test_spawn() {
CPPA_PRINT("test sync send");
CPPA_CHECKPOINT();
auto sync_testee = spawn<blocking_api>([](blocking_actor* self) {
self->receive (
auto sync_testee = spawn<blocking_api>([](blocking_actor* s) {
s->receive (
on("hi", arg_match) >> [&](actor from) {
self->sync_send(from, "whassup?", self).await(
s->sync_send(from, "whassup?", s).await(
on_arg_match >> [&](const string& str) -> string {
CPPA_CHECK(self->last_sender() != nullptr);
CPPA_CHECK(s->last_sender() != nullptr);
CPPA_CHECK_EQUAL(str, "nothing");
return "goodbye!";
},
......@@ -750,15 +752,15 @@ void test_spawn() {
CPPA_CHECKPOINT();
auto inflater = [](event_based_actor* self, const string& name, actor buddy) {
CPPA_LOGF_TRACE(CPPA_ARG(self) << ", " << CPPA_ARG(name)
auto inflater = [](event_based_actor* s, const string& name, actor buddy) {
CPPA_LOGF_TRACE(CPPA_ARG(s) << ", " << CPPA_ARG(name)
<< ", " << CPPA_TARG(buddy, to_string));
self->become(
on_arg_match >> [=](int n, const string& s) {
self->send(buddy, n * 2, s + " from " + name);
s->become(
on_arg_match >> [=](int n, const string& str) {
s->send(buddy, n * 2, str + " from " + name);
},
on(atom("done")) >> [=] {
self->quit();
s->quit();
}
);
};
......@@ -781,15 +783,15 @@ void test_spawn() {
// - the lambda is always executed in the current actor's thread
// but using spawn_next in a message handler could
// still cause undefined behavior!
auto kr34t0r = [&spawn_next](event_based_actor* self, const string& name, actor pal) {
auto kr34t0r = [&spawn_next](event_based_actor* s, const string& name, actor pal) {
if (name == "Joe" && !pal) {
pal = spawn_next("Bob", self);
pal = spawn_next("Bob", s);
}
self->become (
s->become (
others() >> [=] {
// forward message and die
self->send_tuple(pal, self->last_dequeued());
self->quit();
s->send_tuple(pal, s->last_dequeued());
s->quit();
}
);
};
......@@ -832,12 +834,12 @@ void test_spawn() {
// create some actors linked to one single actor
// and kill them all through killing the link
auto legion = spawn([](event_based_actor* self) {
auto legion = spawn([](event_based_actor* s) {
CPPA_PRINT("spawn 100 actors");
for (int i = 0; i < 100; ++i) {
self->spawn<event_testee, linked>();
s->spawn<event_testee, linked>();
}
self->become(others() >> CPPA_UNEXPECTED_MSG_CB());
s->become(others() >> CPPA_UNEXPECTED_MSG_CB());
});
self->send_exit(legion, exit_reason::user_shutdown);
self->await_all_other_actors_done();
......@@ -916,6 +918,8 @@ void test_spawn() {
CPPA_CHECKPOINT();
}
} // namespace <anonymous>
int main() {
CPPA_TEST(test_spawn);
test_spawn();
......
......@@ -5,6 +5,8 @@ using namespace std;
using namespace cppa;
using namespace cppa::placeholders;
namespace {
struct sync_mirror : sb_actor<sync_mirror> {
behavior init_state;
......@@ -179,40 +181,39 @@ void test_sync_send() {
self->on_sync_failure([&] {
CPPA_FAILURE("received: " << to_string(self->last_dequeued()));
});
self->spawn<monitored + blocking_api>([](blocking_actor* self) {
CPPA_LOGC_TRACE("NONE", "main$sync_failure_test", "id = " << self->id());
self->spawn<monitored + blocking_api>([](blocking_actor* s) {
CPPA_LOGC_TRACE("NONE", "main$sync_failure_test", "id = " << s->id());
int invocations = 0;
auto foi = self->spawn<float_or_int, linked>();
self->send(foi, atom("i"));
self->receive(on_arg_match >> [](int i) { CPPA_CHECK_EQUAL(i, 0); });
self->on_sync_failure([=] {
CPPA_FAILURE("received: " << to_string(self->last_dequeued()));
auto foi = s->spawn<float_or_int, linked>();
s->send(foi, atom("i"));
s->receive(on_arg_match >> [](int i) { CPPA_CHECK_EQUAL(i, 0); });
s->on_sync_failure([=] {
CPPA_FAILURE("received: " << to_string(s->last_dequeued()));
});
self->sync_send(foi, atom("i")).await(
s->sync_send(foi, atom("i")).await(
[&](int i) { CPPA_CHECK_EQUAL(i, 0); ++invocations; },
[&](float) { CPPA_UNEXPECTED_MSG(); }
);
self->sync_send(foi, atom("f")).await(
s->sync_send(foi, atom("f")).await(
[&](int) { CPPA_UNEXPECTED_MSG(); },
[&](float f) { CPPA_CHECK_EQUAL(f, 0); ++invocations; }
[&](float f) { CPPA_CHECK_EQUAL(f, 0.f); ++invocations; }
);
//self->exec_behavior_stack();
CPPA_CHECK_EQUAL(invocations, 2);
CPPA_PRINT("trigger sync failure");
// provoke invocation of self->handle_sync_failure()
// provoke invocation of s->handle_sync_failure()
bool sync_failure_called = false;
bool int_handler_called = false;
self->on_sync_failure([&] {
s->on_sync_failure([&] {
sync_failure_called = true;
});
self->sync_send(foi, atom("f")).await(
s->sync_send(foi, atom("f")).await(
on<int>() >> [&] {
int_handler_called = true;
}
);
CPPA_CHECK_EQUAL(sync_failure_called, true);
CPPA_CHECK_EQUAL(int_handler_called, false);
self->quit(exit_reason::user_shutdown);
s->quit(exit_reason::user_shutdown);
});
self->receive (
on_arg_match >> [&](const down_msg& dm) {
......@@ -294,36 +295,36 @@ void test_sync_send() {
CPPA_CHECKPOINT();
// test use case 3
self->spawn<monitored + blocking_api>([](blocking_actor* self) { // client
auto s = self->spawn<server, linked>(); // server
auto w = self->spawn<linked>([](event_based_actor* self) { // worker
self->become(on(atom("request")) >> []{ return atom("response"); });
self->spawn<monitored + blocking_api>([](blocking_actor* s) { // client
auto serv = s->spawn<server, linked>(); // server
auto work = s->spawn<linked>([](event_based_actor* w) { // worker
w->become(on(atom("request")) >> []{ return atom("response"); });
});
// first 'idle', then 'request'
anon_send(s, atom("idle"), w);
self->sync_send(s, atom("request")).await(
anon_send(serv, atom("idle"), work);
s->sync_send(serv, atom("request")).await(
on(atom("response")) >> [=] {
CPPA_CHECKPOINT();
CPPA_CHECK_EQUAL(self->last_sender(), w);
CPPA_CHECK_EQUAL(s->last_sender(), work);
},
others() >> [&] {
CPPA_PRINTERR("unexpected message: "
<< to_string(self->last_dequeued()));
<< to_string(s->last_dequeued()));
}
);
// first 'request', then 'idle'
auto handle = self->sync_send(s, atom("request"));
send_as(w, s, atom("idle"));
auto handle = s->sync_send(serv, atom("request"));
send_as(work, serv, atom("idle"));
handle.await(
on(atom("response")) >> [=] {
CPPA_CHECKPOINT();
CPPA_CHECK_EQUAL(self->last_sender(), w);
CPPA_CHECK_EQUAL(s->last_sender(), work);
},
others() >> CPPA_UNEXPECTED_MSG_CB()
);
self->send(s, "Ever danced with the devil in the pale moonlight?");
s->send(s, "Ever danced with the devil in the pale moonlight?");
// response: {'EXIT', exit_reason::user_shutdown}
self->receive_loop(others() >> CPPA_UNEXPECTED_MSG_CB());
s->receive_loop(others() >> CPPA_UNEXPECTED_MSG_CB());
});
self->receive (
on_arg_match >> [&](const down_msg& dm) {
......@@ -333,11 +334,15 @@ void test_sync_send() {
);
}
} // namespace <anonymous>
int main() {
CPPA_TEST(test_sync_send);
test_sync_send();
await_all_actors_done();
CPPA_CHECKPOINT();
shutdown();
// shutdown warning about unused function (only performs compile-time check)
static_cast<void>(compile_time_optional_variant_check);
return CPPA_TEST_RESULT();
}
......@@ -36,7 +36,22 @@ using namespace cppa;
using namespace cppa::detail;
using namespace cppa::placeholders;
namespace { std::atomic<size_t> s_expensive_copies; }
#define CPPA_CHECK_INVOKED(FunName, Args) \
invoked.clear(); \
if ( !( FunName Args ) || invoked != #FunName ) { \
CPPA_FAILURE("invocation of " #FunName " failed"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
#define CPPA_CHECK_NOT_INVOKED(FunName, Args) \
invoked.clear(); \
if ( FunName Args || invoked == #FunName ) { \
CPPA_FAILURE(#FunName " erroneously invoked"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
namespace {
std::atomic<size_t> s_expensive_copies;
struct expensive_copy_struct {
......@@ -57,11 +72,6 @@ inline bool operator==(const expensive_copy_struct& lhs,
return lhs.value == rhs.value;
}
inline bool operator!=(const expensive_copy_struct& lhs,
const expensive_copy_struct& rhs) {
return !(lhs == rhs);
}
std::string int2str(int i) {
return std::to_string(i);
}
......@@ -75,18 +85,6 @@ optional<int> str2int(const std::string& str) {
return none;
}
#define CPPA_CHECK_INVOKED(FunName, Args) \
invoked.clear(); \
if ( !( FunName Args ) || invoked != #FunName ) { \
CPPA_FAILURE("invocation of " #FunName " failed"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
#define CPPA_CHECK_NOT_INVOKED(FunName, Args) \
invoked.clear(); \
if ( FunName Args || invoked == #FunName ) { \
CPPA_FAILURE(#FunName " erroneously invoked"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
struct dummy_receiver : event_based_actor {
behavior make_behavior() override {
return (
......@@ -455,12 +453,15 @@ void check_drop() {
CPPA_CHECK(t0.take(0).empty());
}
} // namespace <anonymous>
int main() {
CPPA_TEST(test_tuple);
announce<expensive_copy_struct>(&expensive_copy_struct::value);
check_type_list();
check_default_ctors();
check_guards();
check_many_cases();
check_wildcards();
check_move_ops();
check_drop();
......
......@@ -35,6 +35,8 @@
using namespace std;
using namespace cppa;
namespace {
/******************************************************************************
* simple request/response test *
******************************************************************************/
......@@ -312,6 +314,8 @@ void test_sending_typed_actors() {
self->send_exit(aut, exit_reason::user_shutdown);
}
} // namespace <anonymous>
/******************************************************************************
* put it all together *
******************************************************************************/
......
......@@ -19,7 +19,7 @@ struct pseudo_worker {
pseudo_worker() : m_count(0), m_blocked(true) { }
void run() {
void run [[noreturn]] () {
for (;;) {
if (m_blocked) {
yield(yield_state::blocked);
......@@ -33,7 +33,7 @@ struct pseudo_worker {
};
void coroutine(void* worker) {
void coroutine [[noreturn]] (void* worker) {
reinterpret_cast<pseudo_worker*>(worker)->run();
}
......
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