Commit b96539c5 authored by neverlord's avatar neverlord

testing, others(), process_information::get()

parent 14f258ef
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable> <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{07fcd197-092d-45a0-8500-3be614e6ae31}</value> <value type="QString">{23902c37-f07e-47cd-bb19-c366b9f708db}</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
......
...@@ -159,3 +159,5 @@ cppa/detail/get_behavior.hpp ...@@ -159,3 +159,5 @@ cppa/detail/get_behavior.hpp
unit_testing/test__ripemd_160.cpp unit_testing/test__ripemd_160.cpp
cppa/process_information.hpp cppa/process_information.hpp
src/process_information.cpp src/process_information.cpp
cppa/util/ripemd_160.hpp
src/ripemd_160.cpp
...@@ -11,6 +11,9 @@ namespace cppa { ...@@ -11,6 +11,9 @@ namespace cppa {
class serializer; class serializer;
class deserializer; class deserializer;
/**
* @brief
*/
class actor : public channel class actor : public channel
{ {
...@@ -24,18 +27,47 @@ class actor : public channel ...@@ -24,18 +27,47 @@ class actor : public channel
~actor(); ~actor();
/**
* @brief
*/
virtual void join(group_ptr& what) = 0; virtual void join(group_ptr& what) = 0;
/**
* @brief
*/
virtual void leave(const group_ptr& what) = 0; virtual void leave(const group_ptr& what) = 0;
/**
* @brief
*/
virtual void link(intrusive_ptr<actor>& other) = 0; virtual void link(intrusive_ptr<actor>& other) = 0;
/**
* @brief
*/
virtual void unlink(intrusive_ptr<actor>& other) = 0; virtual void unlink(intrusive_ptr<actor>& other) = 0;
/**
* @brief
* @return
*/
virtual bool remove_backlink(const intrusive_ptr<actor>& to) = 0; virtual bool remove_backlink(const intrusive_ptr<actor>& to) = 0;
/**
* @brief
* @return
*/
virtual bool establish_backlink(const intrusive_ptr<actor>& to) = 0; virtual bool establish_backlink(const intrusive_ptr<actor>& to) = 0;
/**
* @brief
* @return
*/
inline std::uint32_t id() const { return m_id; } inline std::uint32_t id() const { return m_id; }
/** /**
* @brief * @brief
* @return
*/ */
static intrusive_ptr<actor> by_id(std::uint32_t actor_id); static intrusive_ptr<actor> by_id(std::uint32_t actor_id);
......
...@@ -2,24 +2,46 @@ ...@@ -2,24 +2,46 @@
#define CONTEXT_HPP #define CONTEXT_HPP
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/exit_signal.hpp"
#include "cppa/message_queue.hpp" #include "cppa/message_queue.hpp"
namespace cppa { namespace cppa {
class scheduler;
/**
*
*/
class context : public actor class context : public actor
{ {
public: friend class scheduler;
virtual message_queue& mailbox() = 0; public:
/** /**
* @brief Default implementation of * @brief Cause this context to send an exit signal to all of its linked
* {@link channel::enqueue(const message&)}. * linked actors and set its state to @c exited.
* */
* Calls <code>mailbox().enqueue(msg)</code>. virtual void quit(std::uint32_t reason) = 0;
*/
virtual void enqueue /*[[override]]*/ (const message& msg); inline void quit(exit_reason reason)
{
quit(static_cast<std::uint32_t>(reason));
}
/**
* @brief
*/
virtual message_queue& mailbox() = 0;
/**
* @brief Default implementation of
* {@link channel::enqueue(const message&)}.
*
* Calls <code>mailbox().enqueue(msg)</code>.
*/
virtual void enqueue /*[[override]]*/ (const message& msg);
}; };
...@@ -31,6 +53,9 @@ context* self(); ...@@ -31,6 +53,9 @@ context* self();
// "private" function // "private" function
void set_self(context*); void set_self(context*);
// "private" function, returns active context (without creating it if needed)
context* unchecked_self();
} // namespace cppa } // namespace cppa
#endif // CONTEXT_HPP #endif // CONTEXT_HPP
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "cppa/context.hpp" #include "cppa/context.hpp"
#include "cppa/message.hpp" #include "cppa/message.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/exit_signal.hpp"
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/actor_behavior.hpp" #include "cppa/actor_behavior.hpp"
#include "cppa/scheduling_hint.hpp" #include "cppa/scheduling_hint.hpp"
...@@ -76,6 +77,16 @@ actor_ptr spawn(F&& what, const Args&... args) ...@@ -76,6 +77,16 @@ actor_ptr spawn(F&& what, const Args&... args)
return spawn<scheduled>(std::forward<F>(what), args...); return spawn<scheduled>(std::forward<F>(what), args...);
} }
inline void quit(std::uint32_t reason)
{
self()->quit(reason);
}
inline void quit(exit_reason reason)
{
self()->quit(reason);
}
inline const message& receive() inline const message& receive()
{ {
return self()->mailbox().dequeue(); return self()->mailbox().dequeue();
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include <map> #include <map>
#include <set> #include <list>
#include <mutex> #include <mutex>
#include "cppa/context.hpp" #include "cppa/context.hpp"
...@@ -28,7 +28,7 @@ class converted_thread_context : public context ...@@ -28,7 +28,7 @@ class converted_thread_context : public context
std::map<group_ptr, group::subscription> m_subscriptions; std::map<group_ptr, group::subscription> m_subscriptions;
// manages actor links // manages actor links
std::set<actor_ptr> m_links; std::list<actor_ptr> m_links;
public: public:
...@@ -38,6 +38,8 @@ class converted_thread_context : public context ...@@ -38,6 +38,8 @@ class converted_thread_context : public context
void join /*[[override]]*/ (group_ptr& what); void join /*[[override]]*/ (group_ptr& what);
void quit /*[[override]]*/ (std::uint32_t reason);
void leave /*[[override]]*/ (const group_ptr& what); void leave /*[[override]]*/ (const group_ptr& what);
void link /*[[override]]*/ (intrusive_ptr<actor>& other); void link /*[[override]]*/ (intrusive_ptr<actor>& other);
......
...@@ -19,7 +19,7 @@ class intermediate : public ref_counted_impl<size_t> ...@@ -19,7 +19,7 @@ class intermediate : public ref_counted_impl<size_t>
}; };
template<typename Impl, typename View> template<typename Impl, typename View = void>
class intermediate_impl : public intermediate class intermediate_impl : public intermediate
{ {
...@@ -40,6 +40,23 @@ class intermediate_impl : public intermediate ...@@ -40,6 +40,23 @@ class intermediate_impl : public intermediate
}; };
template<typename Impl>
class intermediate_impl<Impl, void> : public intermediate
{
Impl m_impl;
public:
intermediate_impl(const Impl& impl) : m_impl(impl) { }
virtual void invoke()
{
m_impl();
}
};
} } // namespace cppa::detail } } // namespace cppa::detail
#endif // INTERMEDIATE_HPP #endif // INTERMEDIATE_HPP
...@@ -28,6 +28,9 @@ enum class exit_reason : std::uint32_t ...@@ -28,6 +28,9 @@ enum class exit_reason : std::uint32_t
}; };
static constexpr std::uint32_t user_defined_exit_reason
= static_cast<std::uint32_t>(exit_reason::user_defined);
/** /**
* @brief Converts {@link exit_reason} to @c std::uint32_t. * @brief Converts {@link exit_reason} to @c std::uint32_t.
*/ */
......
...@@ -16,14 +16,15 @@ namespace cppa { namespace detail { ...@@ -16,14 +16,15 @@ namespace cppa { namespace detail {
struct irb_helper : ref_counted_impl<size_t> struct irb_helper : ref_counted_impl<size_t>
{ {
virtual ~irb_helper() { } virtual ~irb_helper() { }
virtual bool value_cmp(const any_tuple&, virtual bool value_cmp(const any_tuple&, std::vector<size_t>&) const = 0;
std::vector<size_t>&) const = 0;
}; };
template<typename... Types> template<typename... Types>
struct invoke_rule_builder struct invoke_rule_builder
{ {
private:
typedef util::type_list<Types...> types_list; typedef util::type_list<Types...> types_list;
typedef typename util::filter_type_list<any_type, types_list>::type typedef typename util::filter_type_list<any_type, types_list>::type
...@@ -84,7 +85,7 @@ struct invoke_rule_builder ...@@ -84,7 +85,7 @@ struct invoke_rule_builder
{ {
invoke(f, tv); invoke(f, tv);
}; };
if (!m_helper) if (!m_helper) // don't match on values
{ {
auto inv = [f](const any_tuple& t) -> bool auto inv = [f](const any_tuple& t) -> bool
{ {
...@@ -97,19 +98,22 @@ struct invoke_rule_builder ...@@ -97,19 +98,22 @@ struct invoke_rule_builder
} }
return false; return false;
}; };
auto gt = [sub_inv](const any_tuple& t) -> detail::intermediate* auto gt = [sub_inv](const any_tuple& t) -> intermediate*
{ {
std::vector<size_t> mappings; std::vector<size_t> mappings;
if (match<Types...>(t, mappings)) if (match<Types...>(t, mappings))
{ {
tuple_view_type tv(t.vals(), std::move(mappings)); tuple_view_type tv(t.vals(), std::move(mappings));
return new detail::intermediate_impl<decltype(sub_inv), tuple_view_type>(sub_inv, tv); typedef intermediate_impl<decltype(sub_inv),tuple_view_type>
timpl;
return new timpl(sub_inv, tv);
} }
return 0; return 0;
}; };
return invoke_rules(new detail::invokable_impl<decltype(inv), decltype(gt)>(std::move(inv), std::move(gt))); typedef invokable_impl<decltype(inv), decltype(gt)> iimpl;
return invoke_rules(new iimpl(std::move(inv), std::move(gt)));
} }
else else // m_helper matches on values
{ {
auto inv = [f, m_helper](const any_tuple& t) -> bool auto inv = [f, m_helper](const any_tuple& t) -> bool
{ {
...@@ -122,22 +126,47 @@ struct invoke_rule_builder ...@@ -122,22 +126,47 @@ struct invoke_rule_builder
} }
return false; return false;
}; };
auto gt = [sub_inv, m_helper](const any_tuple& t) -> detail::intermediate* auto gt = [sub_inv, m_helper](const any_tuple& t) -> intermediate*
{ {
std::vector<size_t> mappings; std::vector<size_t> mappings;
if (m_helper->value_cmp(t, mappings)) if (m_helper->value_cmp(t, mappings))
{ {
tuple_view_type tv(t.vals(), std::move(mappings)); tuple_view_type tv(t.vals(), std::move(mappings));
return new detail::intermediate_impl<decltype(sub_inv), tuple_view_type>(sub_inv, tv); typedef intermediate_impl<decltype(sub_inv),tuple_view_type>
timpl;
return new timpl(sub_inv, tv);
} }
return 0; return 0;
}; };
return invoke_rules(new detail::invokable_impl<decltype(inv), decltype(gt)>(std::move(inv), std::move(gt))); typedef invokable_impl<decltype(inv), decltype(gt)> iimpl;
return invoke_rules(new iimpl(std::move(inv), std::move(gt)));
} }
} }
}; };
template<>
struct invoke_rule_builder<any_type*>
{
template<typename F>
invoke_rules operator>>(F f)
{
auto inv = [f](const any_tuple&) -> bool
{
f();
return true;
};
auto gt = [f](const any_tuple&) -> intermediate*
{
return new intermediate_impl<decltype(f)>(f);
};
typedef invokable_impl<decltype(inv), decltype(gt)> iimpl;
return invoke_rules(new iimpl(std::move(inv), std::move(gt)));
}
};
} } // cppa::detail } } // cppa::detail
namespace cppa { namespace cppa {
...@@ -148,8 +177,14 @@ inline detail::invoke_rule_builder<Types...> on() ...@@ -148,8 +177,14 @@ inline detail::invoke_rule_builder<Types...> on()
return detail::invoke_rule_builder<Types...>(); return detail::invoke_rule_builder<Types...>();
} }
inline detail::invoke_rule_builder<any_type*> others()
{
return on<any_type*>();
}
template<typename... Types, typename Arg0, typename... Args> template<typename... Types, typename Arg0, typename... Args>
inline detail::invoke_rule_builder<Types...> on(const Arg0& arg0, const Args&... args) inline detail::invoke_rule_builder<Types...> on(const Arg0& arg0,
const Args&... args)
{ {
return detail::invoke_rule_builder<Types...>(arg0, args...); return detail::invoke_rule_builder<Types...>(arg0, args...);
} }
......
...@@ -4,12 +4,14 @@ ...@@ -4,12 +4,14 @@
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include "cppa/util/comparable.hpp"
namespace cppa { namespace cppa {
/** /**
* @brief Identifies a process. * @brief Identifies a process.
*/ */
struct process_information struct process_information : util::comparable<process_information>
{ {
/** /**
...@@ -36,6 +38,9 @@ struct process_information ...@@ -36,6 +38,9 @@ struct process_information
*/ */
static const process_information& get(); static const process_information& get();
// "inherited" from comparable<process_information>
int compare(const process_information& other) const;
}; };
} // namespace cppa } // namespace cppa
......
...@@ -15,6 +15,13 @@ class actor_behavior; ...@@ -15,6 +15,13 @@ class actor_behavior;
class scheduler class scheduler
{ {
protected:
/**
* @brief Calls {@link context::exit(std::uint32_t) context::exit}.
*/
void exit_context(context* ctx, std::uint32_t reason);
public: public:
virtual ~scheduler(); virtual ~scheduler();
......
/******************************************************************************\
* Based on http://homes.esat.kuleuven.be/~cosicart/ps/AB-9601/rmd160.h;
* original header:
*
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
* DATE: 1 March 1996
* VERSION: 1.0
*
* Copyright (c) Katholieke Universiteit Leuven
* 1996, All Rights Reserved
*
* Conditions for use of the RIPEMD-160 Software
*
* The RIPEMD-160 software is freely available for use under the terms and
* conditions described hereunder, which shall be deemed to be accepted by
* any user of the software and applicable on any use of the software:
*
* 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
* all purposes be considered the owner of the RIPEMD-160 software and of
* all copyright, trade secret, patent or other intellectual property
* rights therein.
* 2. The RIPEMD-160 software is provided on an "as is" basis without
* warranty of any sort, express or implied. K.U.Leuven makes no
* representation that the use of the software will not infringe any
* patent or proprietary right of third parties. User will indemnify
* K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
* which may arise as a result of its use of the software. In no
* circumstances K.U.Leuven R&D will be held liable for any deficiency,
* fault or other mishappening with regard to the use or performance of
* the software.
* 3. User agrees to give due credit to K.U.Leuven in scientific publications
* or communications in relation with the use of the RIPEMD-160 software
* as follows: RIPEMD-160 software written by Antoon Bosselaers,
* available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
*
\******************************************************************************/
#ifndef RIPEMD_160_HPP
#define RIPEMD_160_HPP
#include <array>
#include <string>
namespace cppa { namespace util {
std::array<std::uint8_t, 20> ripemd_160(const std::string& data);
} } // namespace cppa::util
#endif // RIPEMD_160_HPP
...@@ -28,6 +28,11 @@ void context::enqueue(const message& msg) ...@@ -28,6 +28,11 @@ void context::enqueue(const message& msg)
mailbox().enqueue(msg); mailbox().enqueue(msg);
} }
context* unchecked_self()
{
return m_this_context.get();
}
context* self() context* self()
{ {
context* result = m_this_context.get(); context* result = m_this_context.get();
......
#include <algorithm>
#include "cppa/exit_signal.hpp"
#include "cppa/detail/converted_thread_context.hpp" #include "cppa/detail/converted_thread_context.hpp"
namespace {
template<class List, typename Element>
bool unique_insert(List& lst, const Element& e)
{
auto end = lst.end();
auto i = std::find(lst.begin(), end, e);
if (i == end)
{
lst.push_back(e);
return true;
}
return false;
}
template<class List, typename Iterator, typename Element>
int erase_all(List& lst, Iterator from, Iterator end, const Element& e)
{
auto i = std::find(from, end, e);
if (i != end)
{
return 1 + erase_all(lst, lst.erase(i), end, e);
}
return 0;
}
template<class List, typename Element>
int erase_all(List& lst, const Element& e)
{
return erase_all(lst, lst.begin(), lst.end(), e);
}
} // namespace <anonymous>
namespace cppa { namespace detail { namespace cppa { namespace detail {
converted_thread_context::converted_thread_context() : m_exited(false) converted_thread_context::converted_thread_context() : m_exited(false)
{ {
} }
void converted_thread_context::quit(std::uint32_t reason)
{
decltype(m_links) mlinks;
decltype(m_subscriptions) msubscriptions;
// lifetime scope of guard
{
std::lock_guard<std::mutex> guard(m_mtx);
m_exited = true;
mlinks = std::move(m_links);
msubscriptions = std::move(m_subscriptions);
// make sure m_links and m_subscriptions definitely are empty
m_links.clear();
m_subscriptions.clear();
}
actor_ptr mself = self();
// send exit messages
for (actor_ptr& aptr : mlinks)
{
aptr->enqueue(message(mself, aptr, exit_signal(reason)));
}
}
void converted_thread_context::link(intrusive_ptr<actor>& other) void converted_thread_context::link(intrusive_ptr<actor>& other)
{ {
std::lock_guard<std::mutex> guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
if (other && !m_exited && other->establish_backlink(this)) if (other && !m_exited && other->establish_backlink(this))
{ {
m_links.insert(other); m_links.push_back(other);
//m_links.insert(other);
} }
} }
...@@ -20,7 +81,7 @@ bool converted_thread_context::remove_backlink(const intrusive_ptr<actor>& other ...@@ -20,7 +81,7 @@ bool converted_thread_context::remove_backlink(const intrusive_ptr<actor>& other
if (other && other != this) if (other && other != this)
{ {
std::lock_guard<std::mutex> guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
return m_links.erase(other) > 0; return erase_all(m_links, other) > 0;//m_links.erase(other) > 0;
} }
return false; return false;
} }
...@@ -36,7 +97,8 @@ bool converted_thread_context::establish_backlink(const intrusive_ptr<actor>& ot ...@@ -36,7 +97,8 @@ bool converted_thread_context::establish_backlink(const intrusive_ptr<actor>& ot
std::lock_guard<std::mutex> guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
if (!m_exited) if (!m_exited)
{ {
result = m_links.insert(other).second; result = unique_insert(m_links, other);
//result = m_links.insert(other).second;
} }
else else
{ {
...@@ -56,7 +118,8 @@ void converted_thread_context::unlink(intrusive_ptr<actor>& other) ...@@ -56,7 +118,8 @@ void converted_thread_context::unlink(intrusive_ptr<actor>& other)
std::lock_guard<std::mutex> guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
if (other && !m_exited && other->remove_backlink(this)) if (other && !m_exited && other->remove_backlink(this))
{ {
m_links.erase(other); erase_all(m_links, other);
//m_links.erase(other);
} }
} }
......
...@@ -32,6 +32,7 @@ void run_actor(cppa::intrusive_ptr<cppa::context> m_self, ...@@ -32,6 +32,7 @@ void run_actor(cppa::intrusive_ptr<cppa::context> m_self,
catch(...) { } catch(...) { }
try { behavior->on_exit(); } try { behavior->on_exit(); }
catch(...) { } catch(...) { }
delete behavior;
} }
if (--m_running_actors <= 1) if (--m_running_actors <= 1)
{ {
...@@ -46,10 +47,14 @@ namespace cppa { namespace detail { ...@@ -46,10 +47,14 @@ namespace cppa { namespace detail {
actor_ptr mock_scheduler::spawn(actor_behavior* ab, scheduling_hint) actor_ptr mock_scheduler::spawn(actor_behavior* ab, scheduling_hint)
{ {
++m_running_actors; if (ab)
intrusive_ptr<context> ctx(new detail::converted_thread_context); {
boost::thread(run_actor, ctx, ab).detach(); ++m_running_actors;
return ctx; intrusive_ptr<context> ctx(new detail::converted_thread_context);
boost::thread(run_actor, ctx, ab).detach();
return ctx;
}
return nullptr;
} }
void mock_scheduler::register_converted_context(context*) void mock_scheduler::register_converted_context(context*)
...@@ -68,8 +73,9 @@ void mock_scheduler::unregister_converted_context(context*) ...@@ -68,8 +73,9 @@ void mock_scheduler::unregister_converted_context(context*)
void mock_scheduler::await_others_done() void mock_scheduler::await_others_done()
{ {
auto expected = (unchecked_self() == nullptr) ? 0 : 1;
boost::mutex::scoped_lock lock(m_ra_mtx); boost::mutex::scoped_lock lock(m_ra_mtx);
while (m_running_actors.load() > 1) while (m_running_actors.load() > expected)
{ {
m_ra_cv.wait(lock); m_ra_cv.wait(lock);
} }
......
#include <cstdio>
#include <cstring>
#include <sstream> #include <sstream>
#include <unistd.h>
#include <sys/types.h>
#include "cppa/util/ripemd_160.hpp"
#include "cppa/process_information.hpp" #include "cppa/process_information.hpp"
namespace {
void erase_trailing_newline(std::string& str)
{
while (!str.empty() && (*str.rbegin()) == '\n')
{
str.resize(str.size() - 1);
}
}
cppa::process_information compute_proc_info()
{
cppa::process_information result;
result.process_id = getpid();
char cbuf[100];
// fetch hd serial
std::string hd_serial;
FILE* cmd = popen("/usr/sbin/diskutil info / | "
"/usr/bin/awk '$0 ~ /UUID/ { print $3 }'",
"r");
while (fgets(cbuf, 100, cmd) != 0)
{
hd_serial += cbuf;
}
pclose(cmd);
erase_trailing_newline(hd_serial);
// fetch mac address of first network device
std::string first_mac_addr;
cmd = popen("/usr/sbin/system_profiler SPNetworkDataType | "
"/usr/bin/grep -Fw MAC | "
"/usr/bin/grep -o \"..:..:..:..:..:..\" | "
"/usr/bin/head -n1",
"r");
while (fgets(cbuf, 100, cmd) != 0)
{
first_mac_addr += cbuf;
}
pclose(cmd);
erase_trailing_newline(first_mac_addr);
auto tmp = cppa::util::ripemd_160(first_mac_addr + hd_serial);
memcpy(result.node_id, tmp.data(), 20);
return result;
}
} // namespace <anonymous>
namespace cppa { namespace cppa {
std::string process_information::node_id_as_string() const std::string process_information::node_id_as_string() const
{ {
std::ostringstream oss; std::ostringstream oss;
oss << std::hex; oss << std::hex;
oss.fill('0');
for (size_t i = 0; i < 20; ++i) for (size_t i = 0; i < 20; ++i)
{ {
oss.width(2); oss.width(2);
oss.fill('0');
oss << static_cast<std::uint32_t>(node_id[i]); oss << static_cast<std::uint32_t>(node_id[i]);
} }
return oss.str(); return oss.str();
...@@ -19,7 +72,21 @@ std::string process_information::node_id_as_string() const ...@@ -19,7 +72,21 @@ std::string process_information::node_id_as_string() const
const process_information& process_information::get() const process_information& process_information::get()
{ {
static auto s_proc_info = compute_proc_info();
return s_proc_info;
}
int process_information::compare(const process_information& other) const
{
int tmp = strncmp(reinterpret_cast<const char*>(node_id),
reinterpret_cast<const char*>(other.node_id), 20);
if (tmp == 0)
{
if (process_id < other.process_id) return -1;
else if (process_id == other.process_id) return 0;
return 1;
}
return tmp;
} }
} // namespace cppa } // namespace cppa
/******************************************************************************\
* Based on http://homes.esat.kuleuven.be/~cosicart/ps/AB-9601/rmd160.c;
* original header:
*
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
* DATE: 1 March 1996
* VERSION: 1.0
*
* Copyright (c) Katholieke Universiteit Leuven
* 1996, All Rights Reserved
*
* Conditions for use of the RIPEMD-160 Software
*
* The RIPEMD-160 software is freely available for use under the terms and
* conditions described hereunder, which shall be deemed to be accepted by
* any user of the software and applicable on any use of the software:
*
* 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
* all purposes be considered the owner of the RIPEMD-160 software and of
* all copyright, trade secret, patent or other intellectual property
* rights therein.
* 2. The RIPEMD-160 software is provided on an "as is" basis without
* warranty of any sort, express or implied. K.U.Leuven makes no
* representation that the use of the software will not infringe any
* patent or proprietary right of third parties. User will indemnify
* K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
* which may arise as a result of its use of the software. In no
* circumstances K.U.Leuven R&D will be held liable for any deficiency,
* fault or other mishappening with regard to the use or performance of
* the software.
* 3. User agrees to give due credit to K.U.Leuven in scientific publications
* or communications in relation with the use of the RIPEMD-160 software
* as follows: RIPEMD-160 software written by Antoon Bosselaers,
* available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
*
\******************************************************************************/
#include <cstring>
#include "cppa/util/ripemd_160.hpp"
namespace {
/* typedef 8 and 32 bit types, resp. */
/* adapt these, if necessary,
for your operating system and compiler */
typedef unsigned char byte;
typedef std::uint32_t dword;
/* macro definitions */
/* collect four bytes into one word: */
#define BYTES_TO_DWORD(strptr) \
(((dword) *((strptr)+3) << 24) | \
((dword) *((strptr)+2) << 16) | \
((dword) *((strptr)+1) << 8) | \
((dword) *(strptr)))
/* ROL(x, n) cyclically rotates x over n bits to the left */
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define II(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define FFF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GGG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HHH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define III(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
void MDinit(dword *MDbuf)
{
MDbuf[0] = 0x67452301UL;
MDbuf[1] = 0xefcdab89UL;
MDbuf[2] = 0x98badcfeUL;
MDbuf[3] = 0x10325476UL;
MDbuf[4] = 0xc3d2e1f0UL;
}
void compress(dword *MDbuf, dword *X)
{
dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
dd = MDbuf[3], ee = MDbuf[4];
dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
ddd = MDbuf[3], eee = MDbuf[4];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
/* combine results */
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
MDbuf[1] = MDbuf[2] + dd + eee;
MDbuf[2] = MDbuf[3] + ee + aaa;
MDbuf[3] = MDbuf[4] + aa + bbb;
MDbuf[4] = MDbuf[0] + bb + ccc;
MDbuf[0] = ddd;
return;
}
void MDfinish(dword *MDbuf, const byte *strptr, dword lswlen, dword mswlen)
{
unsigned int i; /* counter */
dword X[16]; /* message words */
memset(X, 0, 16 * sizeof(dword));
/* put bytes from strptr into X */
for (i=0; i<(lswlen&63); i++) {
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
}
/* append the bit m_n == 1 */
X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
if ((lswlen & 63) > 55) {
/* length goes to next block */
compress(MDbuf, X);
memset(X, 0, 16*sizeof(dword));
}
/* append length in bits*/
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
compress(MDbuf, X);
return;
}
} // namespace <anonmyous>
namespace cppa { namespace util {
std::array<std::uint8_t, 20> ripemd_160(const std::string& data)
{
dword MDbuf[5]; /* contains (A, B, C, D(, E)) */
dword X[16]; /* current 16-word chunk */
dword length; /* length in bytes of message */
auto message = reinterpret_cast<const unsigned char*>(data.c_str());
/* initialize */
MDinit(MDbuf);
length = data.size();
/* process message in 16-word chunks */
for (dword nbytes = length; nbytes > 63; nbytes -= 64)
{
for (dword i = 0; i < 16; ++i)
{
X[i] = BYTES_TO_DWORD(message);
message += 4;
}
compress(MDbuf, X);
}
/* length mod 64 bytes left */
/* finish: */
MDfinish(MDbuf, message, length, 0);
std::array<std::uint8_t, 20> result;
for (size_t i = 0; i < result.size(); i += 4)
{
result[i] = MDbuf[i>>2]; /* implicit cast to byte */
result[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
result[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
result[i+3] = (MDbuf[i>>2] >> 24);
}
return result;
}
} } // namespace cppa::util
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#define _GLIBCXX_HAS_GTHREADS #define _GLIBCXX_HAS_GTHREADS
#include <mutex> #include <mutex>
#include "cppa/context.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/detail/mock_scheduler.hpp" #include "cppa/detail/mock_scheduler.hpp"
...@@ -15,22 +16,29 @@ std::atomic<cppa::scheduler*> m_instance; ...@@ -15,22 +16,29 @@ std::atomic<cppa::scheduler*> m_instance;
namespace cppa { namespace cppa {
scheduler::~scheduler() { } scheduler::~scheduler()
{
}
void scheduler::exit_context(context* ctx, std::uint32_t reason)
{
ctx->quit(reason);
}
scheduler* get_scheduler() scheduler* get_scheduler()
{ {
scheduler* result = m_instance.load(); scheduler* result = m_instance.load();
if (!result) if (!result)
{ {
std::lock_guard<std::mutex> lock(m_instance_mtx); std::lock_guard<std::mutex> lock(m_instance_mtx);
result = m_instance.load(); result = m_instance.load();
if (!result) if (!result)
{ {
result = new detail::mock_scheduler; result = new detail::mock_scheduler;
m_instance.store(result); m_instance.store(result);
} }
} }
return result; return result;
} }
} // namespace cppa } // namespace cppa
...@@ -157,7 +157,6 @@ class actor_ptr_tinfo : public util::abstract_uniform_type_info<actor_ptr> ...@@ -157,7 +157,6 @@ class actor_ptr_tinfo : public util::abstract_uniform_type_info<actor_ptr>
} }
} }
protected: protected:
void serialize(const void* ptr, serializer* sink) const void serialize(const void* ptr, serializer* sink) const
......
...@@ -64,360 +64,3 @@ unsigned int hash_of(const std::string& what) ...@@ -64,360 +64,3 @@ unsigned int hash_of(const std::string& what)
{ {
return MurmurHash2(what.c_str(), what.size(), 0x15091984); return MurmurHash2(what.c_str(), what.size(), 0x15091984);
} }
namespace {
/* typedef 8 and 32 bit types, resp. */
/* adapt these, if necessary,
for your operating system and compiler */
typedef unsigned char byte;
typedef std::uint32_t dword;
/* macro definitions */
/* collect four bytes into one word: */
#define BYTES_TO_DWORD(strptr) \
(((dword) *((strptr)+3) << 24) | \
((dword) *((strptr)+2) << 16) | \
((dword) *((strptr)+1) << 8) | \
((dword) *(strptr)))
/* ROL(x, n) cyclically rotates x over n bits to the left */
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define II(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define FFF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GGG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HHH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define III(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
void MDinit(dword *MDbuf)
{
MDbuf[0] = 0x67452301UL;
MDbuf[1] = 0xefcdab89UL;
MDbuf[2] = 0x98badcfeUL;
MDbuf[3] = 0x10325476UL;
MDbuf[4] = 0xc3d2e1f0UL;
}
void compress(dword *MDbuf, dword *X)
{
dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
dd = MDbuf[3], ee = MDbuf[4];
dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
ddd = MDbuf[3], eee = MDbuf[4];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
/* combine results */
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
MDbuf[1] = MDbuf[2] + dd + eee;
MDbuf[2] = MDbuf[3] + ee + aaa;
MDbuf[3] = MDbuf[4] + aa + bbb;
MDbuf[4] = MDbuf[0] + bb + ccc;
MDbuf[0] = ddd;
return;
}
void MDfinish(dword *MDbuf, const byte *strptr, dword lswlen, dword mswlen)
{
unsigned int i; /* counter */
dword X[16]; /* message words */
memset(X, 0, 16 * sizeof(dword));
/* put bytes from strptr into X */
for (i=0; i<(lswlen&63); i++) {
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
}
/* append the bit m_n == 1 */
X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
if ((lswlen & 63) > 55) {
/* length goes to next block */
compress(MDbuf, X);
memset(X, 0, 16*sizeof(dword));
}
/* append length in bits*/
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
compress(MDbuf, X);
return;
}
} // namespace <anonmyous>
hash_result_160bit ripemd_160(const std::string& data)
{
dword MDbuf[5]; /* contains (A, B, C, D(, E)) */
dword X[16]; /* current 16-word chunk */
dword length; /* length in bytes of message */
const unsigned char* message = reinterpret_cast<const unsigned char*>(data.c_str());
/* initialize */
MDinit(MDbuf);
length = data.size();
/* process message in 16-word chunks */
for (dword nbytes = length; nbytes > 63; nbytes -= 64)
{
for (dword i = 0; i < 16; ++i)
{
X[i] = BYTES_TO_DWORD(message);
message += 4;
}
compress(MDbuf, X);
}
/* length mod 64 bytes left */
/* finish: */
MDfinish(MDbuf, message, length, 0);
hash_result_160bit result;
for (size_t i = 0; i < result.size(); i += 4)
{
result[i] = MDbuf[i>>2]; /* implicit cast to byte */
result[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
result[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
result[i+3] = (MDbuf[i>>2] >> 24);
}
return result;
}
...@@ -2,49 +2,8 @@ ...@@ -2,49 +2,8 @@
#define HASH_OF_HPP #define HASH_OF_HPP
#include <string> #include <string>
#include <ostream>
#include <cstdint>
#include <stdexcept>
unsigned int hash_of(const std::string& what); unsigned int hash_of(const std::string& what);
unsigned int hash_of(const char* what, int what_length); unsigned int hash_of(const char* what, int what_length);
struct hash_result_160bit
{
std::uint8_t data[20];
inline std::uint8_t& operator[](size_t p)
{
return data[p];
}
inline std::uint8_t operator[](size_t p) const
{
return data[p];
}
inline size_t size() const
{
return 20;
}
};
namespace std {
inline ostream& operator<<(ostream& o, const hash_result_160bit& res)
{
auto flags = o.flags();
o << std::hex;
for (size_t i = 0; i < res.size(); ++i)
{
o.width(2);
o.fill('0');
o << static_cast<std::uint32_t>(res[i]);
}
// restore flags afterwards
o.flags(flags);
return o;
}
} // namespace std
hash_result_160bit ripemd_160(const std::string& data);
#endif // HASH_OF_HPP #endif // HASH_OF_HPP
...@@ -12,15 +12,13 @@ ...@@ -12,15 +12,13 @@
#include <typeinfo> #include <typeinfo>
#include <iostream> #include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include "test.hpp" #include "test.hpp"
#include "hash_of.hpp" #include "hash_of.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/process_information.hpp"
#define RUN_TEST(fun_name) \ #define RUN_TEST(fun_name) \
std::cout << "run " << #fun_name << " ..." << std::endl; \ std::cout << "run " << #fun_name << " ..." << std::endl; \
...@@ -31,100 +29,10 @@ using std::cout; ...@@ -31,100 +29,10 @@ using std::cout;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
/**
* @brief Identifies a process.
*/
struct process_information
{
/**
* @brief Identifies the host system.
*
* A hash build from the MAC address of the first network device
* and the serial number from the root HD (mounted in "/" or "C:").
*/
std::uint8_t node_id[20];
/**
* @brief Identifies the running process.
*/
std::uint32_t process_id;
/**
* @brief Converts {@link node_id} to an hexadecimal string.
*/
std::string node_id_as_string() const
{
std::ostringstream oss;
oss << std::hex;
for (size_t i = 0; i < 20; ++i)
{
oss.width(2);
oss.fill('0');
oss << static_cast<std::uint32_t>(node_id[i]);
}
return oss.str();
}
};
namespace {
void erase_trailing_newline(std::string& str)
{
while (!str.empty() && (*str.rbegin()) == '\n')
{
str.resize(str.size() - 1);
}
}
process_information compute_proc_info()
{
process_information result;
result.process_id = getpid();
char cbuf[100];
// fetch hd serial
std::string hd_serial;
FILE* cmd = popen("/usr/sbin/diskutil info / | "
"/usr/bin/awk '$0 ~ /UUID/ { print $3 }'",
"r");
while (fgets(cbuf, 100, cmd) != 0)
{
hd_serial += cbuf;
}
pclose(cmd);
erase_trailing_newline(hd_serial);
// fetch mac address of first network device
std::string first_mac_addr;
cmd = popen("/usr/sbin/system_profiler SPNetworkDataType | "
"/usr/bin/grep -Fw MAC | "
"/usr/bin/grep -o \"..:..:..:..:..:..\" | "
"/usr/bin/head -n1",
"r");
while (fgets(cbuf, 100, cmd) != 0)
{
first_mac_addr += cbuf;
}
pclose(cmd);
erase_trailing_newline(first_mac_addr);
hash_result_160bit tmp = ripemd_160(first_mac_addr + hd_serial);
memcpy(result.node_id, tmp.data, 20);
return result;
}
} // namespace <anonymous>
const process_information& get_process_information()
{
static auto s_proc_info = compute_proc_info();
return s_proc_info;
}
void print_node_id() void print_node_id()
{ {
const auto& pinfo = get_process_information(); const auto& pinfo = cppa::process_information::get();
// lifetime scope of oss auto node_id_hash = pinfo.node_id_as_string();
std::string node_id_hash = pinfo.node_id_as_string();
cout << "node id: " << node_id_hash << endl; cout << "node id: " << node_id_hash << endl;
cout << "process id: " << pinfo.process_id << endl; cout << "process id: " << pinfo.process_id << endl;
cout << "actor id format: {process id}.{actor id}@{node id}" << endl; cout << "actor id format: {process id}.{actor id}@{node id}" << endl;
...@@ -137,7 +45,8 @@ void print_node_id() ...@@ -137,7 +45,8 @@ void print_node_id()
int main(int argc, char** c_argv) int main(int argc, char** c_argv)
{ {
print_node_id(); print_node_id();
return 0; cout << endl << endl;
//return 0;
std::vector<std::string> argv; std::vector<std::string> argv;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
......
...@@ -42,9 +42,6 @@ baz; ...@@ -42,9 +42,6 @@ baz;
size_t test__local_group() size_t test__local_group()
{ {
CPPA_TEST(test__local_group); CPPA_TEST(test__local_group);
/*
baz << make_tuple(1, 2, 3);
auto foo_group = group::get("local", "foo"); auto foo_group = group::get("local", "foo");
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
...@@ -60,6 +57,5 @@ size_t test__local_group() ...@@ -60,6 +57,5 @@ size_t test__local_group()
} }
CPPA_CHECK_EQUAL(result, 10); CPPA_CHECK_EQUAL(result, 10);
await_all_others_done(); await_all_others_done();
*/
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT;
} }
...@@ -2,14 +2,24 @@ ...@@ -2,14 +2,24 @@
#include <iostream> #include <iostream>
#include "test.hpp" #include "test.hpp"
#include "hash_of.hpp"
#include "cppa/util/ripemd_160.hpp"
using cppa::util::ripemd_160;
namespace { namespace {
std::string str_hash(const std::string& what) std::string str_hash(const std::string& what)
{ {
auto hash = ripemd_160(what);
std::ostringstream oss; std::ostringstream oss;
oss << ripemd_160(what); oss << std::hex;
for (auto i : hash)
{
oss.width(2);
oss.fill('0');
oss << static_cast<std::uint32_t>(i);
}
return oss.str(); return oss.str();
} }
......
#define CPPA_VERBOSE_CHECK
#include <iostream> #include <iostream>
#include <functional> #include <functional>
...@@ -6,6 +8,7 @@ ...@@ -6,6 +8,7 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/to_string.hpp"
using std::cout; using std::cout;
using std::endl; using std::endl;
...@@ -17,24 +20,32 @@ using namespace cppa; ...@@ -17,24 +20,32 @@ using namespace cppa;
void pong(actor_ptr ping_actor) void pong(actor_ptr ping_actor)
{ {
link(ping_actor); link(ping_actor);
bool quit = false; bool done = false;
// kickoff // kickoff
ping_actor << make_tuple(0); // or: send(ping_actor, 0); ping_actor << make_tuple(0); // or: send(ping_actor, 0);
// invoke rules // invoke rules
auto rules = (on<std::int32_t>(9) >> [&]() { quit = true; }, auto rules = (on<std::int32_t>(9) >> [&]() { done = true; },
on<std::int32_t>() >> [](int v) { reply(v+1); }); on<std::int32_t>() >> [](int v) { reply(v+1); });
// loop // loop
while (!quit) receive(rules); while (!done) receive(rules);
// terminate with non-normal exit reason to
// force ping actor to quit
quit(user_defined_exit_reason);
} }
void ping() void ping()
{ {
// invoke rule // invoke rule
auto rule = on<std::int32_t>() >> [](std::int32_t v) auto rule = (on<std::int32_t>() >> [](std::int32_t v)
{ {
++pings; ++pings;
reply(v+1); reply(v+1);
}; },
others() >> []()
{
cout << to_string(last_received())
<< endl;
});
// loop // loop
for (;;) receive(rule); for (;;) receive(rule);
} }
......
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