Commit 14f258ef authored by neverlord's avatar neverlord

ripemd160, process id, node id

parent 1b4c24c2
...@@ -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">{23902c37-f07e-47cd-bb19-c366b9f708db}</value> <value type="QString">{07fcd197-092d-45a0-8500-3be614e6ae31}</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
......
...@@ -156,3 +156,6 @@ cppa/util/if_else.hpp ...@@ -156,3 +156,6 @@ cppa/util/if_else.hpp
cppa/util/pop_back.hpp cppa/util/pop_back.hpp
cppa/util/pt_dispatch.hpp cppa/util/pt_dispatch.hpp
cppa/detail/get_behavior.hpp cppa/detail/get_behavior.hpp
unit_testing/test__ripemd_160.cpp
cppa/process_information.hpp
src/process_information.cpp
...@@ -51,6 +51,16 @@ ...@@ -51,6 +51,16 @@
namespace cppa { namespace cppa {
inline void link(actor_ptr& other)
{
self()->link(other);
}
inline void link(actor_ptr&& other)
{
self()->link(other);
}
template<scheduling_hint Hint, typename F, typename... Args> template<scheduling_hint Hint, typename F, typename... Args>
actor_ptr spawn(F&& what, const Args&... args) actor_ptr spawn(F&& what, const Args&... args)
{ {
......
#ifndef PROCESS_INFORMATION_HPP
#define PROCESS_INFORMATION_HPP
#include <string>
#include <cstdint>
namespace cppa {
/**
* @brief Identifies a process.
*/
struct process_information
{
/**
* @brief Identifies the running process.
*/
std::uint32_t process_id;
/**
* @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 Converts {@link node_id} to an hexadecimal string.
*/
std::string node_id_as_string() const;
/**
* @brief Returns the proccess_information for the running process.
* @return
*/
static const process_information& get();
};
} // namespace cppa
#endif // PROCESS_INFORMATION_HPP
#include <sstream>
#include "cppa/process_information.hpp"
namespace cppa {
std::string process_information::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();
}
const process_information& process_information::get()
{
}
} // namespace cppa
...@@ -17,6 +17,7 @@ SOURCES = hash_of.cpp \ ...@@ -17,6 +17,7 @@ SOURCES = hash_of.cpp \
test__local_group.cpp \ test__local_group.cpp \
test__primitive_variant.cpp \ test__primitive_variant.cpp \
test__queue_performance.cpp \ test__queue_performance.cpp \
test__ripemd_160.cpp \
test__serialization.cpp \ test__serialization.cpp \
test__spawn.cpp \ test__spawn.cpp \
test__tuple.cpp \ test__tuple.cpp \
......
This diff is collapsed.
...@@ -2,8 +2,49 @@ ...@@ -2,8 +2,49 @@
#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
#include <map> #include <map>
#include <cstdio>
#include <atomic> #include <atomic>
#include <string> #include <string>
#include <limits> #include <limits>
#include <vector> #include <vector>
#include <cstring>
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <sstream>
#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 "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
...@@ -24,36 +31,137 @@ using std::cout; ...@@ -24,36 +31,137 @@ 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()
{
const auto& pinfo = get_process_information();
// lifetime scope of oss
std::string node_id_hash = pinfo.node_id_as_string();
cout << "node id: " << node_id_hash << endl;
cout << "process id: " << pinfo.process_id << endl;
cout << "actor id format: {process id}.{actor id}@{node id}" << endl;
cout << "example actor id: " << pinfo.process_id
<< ".42@"
<< node_id_hash
<< endl;
}
int main(int argc, char** c_argv) int main(int argc, char** c_argv)
{ {
print_node_id();
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)
{ {
argv.push_back(c_argv[i]); argv.push_back(c_argv[i]);
} }
if (!argv.empty()) if (!argv.empty())
{ {
if (argv.size() == 1 && argv.front() == "performance_test") if (argv.size() == 1 && argv.front() == "performance_test")
{ {
cout << endl << "run queue performance test ... " << endl; cout << endl << "run queue performance test ... " << endl;
test__queue_performance(); test__queue_performance();
return 0;
} }
else else
{ {
cerr << "unrecognized options" cerr << "usage: test [performance_test]" << endl;
<< endl
<< "no options:\n\tunit tests"
<< endl
<< "performance_test:\n\trun single reader queue tests"
<< endl;
} }
} }
else else
{ {
std::cout << std::boolalpha; std::cout << std::boolalpha;
size_t errors = 0; size_t errors = 0;
RUN_TEST(test__ripemd_160);
RUN_TEST(test__primitive_variant); RUN_TEST(test__primitive_variant);
RUN_TEST(test__uniform_type); RUN_TEST(test__uniform_type);
RUN_TEST(test__intrusive_ptr); RUN_TEST(test__intrusive_ptr);
......
...@@ -46,6 +46,7 @@ std::cerr << err_msg << std::endl; \ ...@@ -46,6 +46,7 @@ std::cerr << err_msg << std::endl; \
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) == (rhs_loc))) #define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) == (rhs_loc)))
size_t test__ripemd_160();
size_t test__uniform_type(); size_t test__uniform_type();
size_t test__type_list(); size_t test__type_list();
size_t test__a_matches_b(); size_t test__a_matches_b();
......
...@@ -42,7 +42,7 @@ baz; ...@@ -42,7 +42,7 @@ 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); baz << make_tuple(1, 2, 3);
auto foo_group = group::get("local", "foo"); auto foo_group = group::get("local", "foo");
...@@ -60,5 +60,6 @@ size_t test__local_group() ...@@ -60,5 +60,6 @@ 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;
} }
#include <sstream>
#include <iostream>
#include "test.hpp"
#include "hash_of.hpp"
namespace {
std::string str_hash(const std::string& what)
{
std::ostringstream oss;
oss << ripemd_160(what);
return oss.str();
}
} // namespace <anonymous>
// verify ripemd implementation with example hash results from
// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
size_t test__ripemd_160()
{
CPPA_TEST(test__ripemd_160);
CPPA_CHECK_EQUAL(str_hash(""),
"9c1185a5c5e9fc54612808977ee8f548b2258d31");
CPPA_CHECK_EQUAL(str_hash("a"),
"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
CPPA_CHECK_EQUAL(str_hash("abc"),
"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
CPPA_CHECK_EQUAL(str_hash("message digest"),
"5d0689ef49d2fae572b881b123a85ffa21595f36");
CPPA_CHECK_EQUAL(str_hash("abcdefghijklmnopqrstuvwxyz"),
"f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
CPPA_CHECK_EQUAL(str_hash("abcdbcdecdefdefgefghfghighij"
"hijkijkljklmklmnlmnomnopnopq"),
"12a053384a9c0c88e405a06c27dcf49ada62eb2b");
CPPA_CHECK_EQUAL(str_hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
"fghijklmnopqrstuvwxyz0123456789"),
"b0e20b6e3116640286ed3a87a5713079b21f5189");
CPPA_CHECK_EQUAL(str_hash("1234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890"),
"9b752e45573d4b39f4dbd3323cab82bf63326bfb");
//CPPA_CHECK_EQUAL(str_hash(std::string(1000000, 'a')),
// "52783243c1697bdbe16d37f97f68f08325dc1528");
return CPPA_TEST_RESULT;
}
...@@ -10,13 +10,39 @@ ...@@ -10,13 +10,39 @@
using std::cout; using std::cout;
using std::endl; using std::endl;
namespace { int pings = 0; }
using namespace cppa; using namespace cppa;
void pong() void pong(actor_ptr ping_actor)
{ {
receive(on<int>() >> [](int value) { link(ping_actor);
reply((value * 20) + 2); bool quit = false;
}); // kickoff
ping_actor << make_tuple(0); // or: send(ping_actor, 0);
// invoke rules
auto rules = (on<std::int32_t>(9) >> [&]() { quit = true; },
on<std::int32_t>() >> [](int v) { reply(v+1); });
// loop
while (!quit) receive(rules);
}
void ping()
{
// invoke rule
auto rule = on<std::int32_t>() >> [](std::int32_t v)
{
++pings;
reply(v+1);
};
// loop
for (;;) receive(rule);
}
void pong_example()
{
spawn(pong, spawn(ping));
await_all_others_done();
} }
void echo(actor_ptr whom, int what) void echo(actor_ptr whom, int what)
...@@ -27,6 +53,9 @@ void echo(actor_ptr whom, int what) ...@@ -27,6 +53,9 @@ void echo(actor_ptr whom, int what)
size_t test__spawn() size_t test__spawn()
{ {
CPPA_TEST(test__spawn); CPPA_TEST(test__spawn);
pong_example();
CPPA_CHECK_EQUAL(pings, 5);
/*
actor_ptr self_ptr = self(); actor_ptr self_ptr = self();
{ {
spawn(echo, self_ptr, 1); spawn(echo, self_ptr, 1);
...@@ -63,5 +92,6 @@ size_t test__spawn() ...@@ -63,5 +92,6 @@ size_t test__spawn()
CPPA_CHECK(received_echo); CPPA_CHECK(received_echo);
} }
await_all_others_done(); await_all_others_done();
*/
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT;
} }
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