Commit 1613ffb2 authored by Dominik Charousset's avatar Dominik Charousset

Reformatted according to new coding style

parent 3ed9bf70
--- ---
AccessModifierOffset: -1 AccessModifierOffset: -2
AlignEscapedNewlinesLeft: false AlignEscapedNewlinesLeft: false
AlignTrailingComments: true AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: true AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true AlwaysBreakTemplateDeclarations: true
BinPackParameters: true BinPackParameters: true
......
...@@ -40,6 +40,9 @@ Commit Message Style ...@@ -40,6 +40,9 @@ Commit Message Style
characters. It is capitalized and written in and imperative present tense: characters. It is capitalized and written in and imperative present tense:
e.g., "Fix bug" as opposed to "Fixes bug" or "Fixed bug". e.g., "Fix bug" as opposed to "Fixes bug" or "Fixed bug".
- The first line does not contain a dot at the end. (Think of it as the header
of the following description).
- The second line is empty. - The second line is empty.
- Optional long descriptions as full sentences begin on the third line, - Optional long descriptions as full sentences begin on the third line,
...@@ -52,7 +55,7 @@ Coding Style ...@@ -52,7 +55,7 @@ Coding Style
When contributing source code, please adhere to the following coding style, When contributing source code, please adhere to the following coding style,
whwich is loosely based on the [Google C++ Style whwich is loosely based on the [Google C++ Style
Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml) and the Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml) and the
coding conventions used by the STL. coding conventions used by the C++ Standard Library.
Example for the Impatient Example for the Impatient
...@@ -66,58 +69,44 @@ Example for the Impatient ...@@ -66,58 +69,44 @@ Example for the Impatient
#include <string> #include <string>
// use "//" for regular comments and "///" for doxygen
namespace caf { namespace caf {
namespace example { namespace example {
/** /// This class is only being used as style guide example.
* This class is only being used as style guide example.
*/
class my_class { class my_class {
public: public:
/** /// Brief description. More description. Note that CAF uses the
* Brief description. More description. Note that CAF uses the /// "JavaDoc-style" autobrief option, i.e., everything up until the
* "JavaDoc-style" autobrief option, i.e., everything up until the /// first dot is the brief description.
* first dot is the brief description.
*/
my_class(); my_class();
/** /// Destructs `my_class`. Please use Markdown in comments.
* Destructs `my_class`. Please use Markdown in comments.
*/
~my_class(); ~my_class();
// do not use the @return if you start the brief description with "Returns" // suppress redundant @return if you start the brief description with "Returns"
/** /// Returns the name of this instance.
* Returns the name of this instance.
*/
inline const std::string& name() const { inline const std::string& name() const {
return m_name; return name_;
} }
/** /// Sets the name of this instance.
* Sets the name of this instance. inline void name(const std::string& new_name) {
*/ name_ = new_name;
inline void name(std::string new_name) {
m_name = std::move(new_name);
} }
/** /// Prints the name to `STDIN`.
* Prints the name to `STDIN`.
*/
void print_name() const; void print_name() const;
/** /// Does something (maybe).
* Does something (maybe).
*/
void do_something(); void do_something();
/** /// Does something else.
* Does something else.
*/
void do_something_else(); void do_something_else();
private: private:
std::string m_name; std::string name_;
}; };
} // namespace example } // namespace example
...@@ -142,7 +131,7 @@ constexpr const char default_name[] = "my object"; ...@@ -142,7 +131,7 @@ constexpr const char default_name[] = "my object";
} // namespace <anonymous> } // namespace <anonymous>
my_class::my_class() : m_name(default_name) { my_class::my_class() : name_(default_name) {
// nop // nop
} }
...@@ -167,7 +156,7 @@ void my_class::do_something() { ...@@ -167,7 +156,7 @@ void my_class::do_something() {
} }
} }
void::my_class::do_something_else() { void my_class::do_something_else() {
switch (default_name[0]) { switch (default_name[0]) {
case 'a': case 'a':
// handle a // handle a
...@@ -186,14 +175,16 @@ void::my_class::do_something_else() { ...@@ -186,14 +175,16 @@ void::my_class::do_something_else() {
``` ```
General rules General
------------- -------
- Use 2 spaces per indentation level. - Use 2 spaces per indentation level.
- The maximum number of characters per line is 80. - The maximum number of characters per line is 80.
- Never use tabs. - No tabs, ever.
- Never use C-style casts.
- Vertical whitespaces separate functions and are not used inside functions: - Vertical whitespaces separate functions and are not used inside functions:
use comments to document logical blocks. use comments to document logical blocks.
...@@ -204,11 +195,10 @@ General rules ...@@ -204,11 +195,10 @@ General rules
- `*` and `&` bind to the *type*, e.g., `const std::string& arg`. - `*` and `&` bind to the *type*, e.g., `const std::string& arg`.
- Namespaces do not increase the indentation level. - Namespaces and access modifiers (e.g., `public`) do not increase the
indentation level.
- Access modifiers, e.g. `public`, are indented one space.
- Use the order `public`, `protected`, and then `private`. - In a class, use the order `public`, `protected`, and then `private`.
- Always use `auto` to declare a variable unless you cannot initialize it - Always use `auto` to declare a variable unless you cannot initialize it
immediately or if you actually want a type conversion. In the latter case, immediately or if you actually want a type conversion. In the latter case,
...@@ -216,23 +206,25 @@ General rules ...@@ -216,23 +206,25 @@ General rules
- Never use unwrapped, manual resource management such as `new` and `delete`. - Never use unwrapped, manual resource management such as `new` and `delete`.
- Do not use `typedef`. The syntax provided by `using` is much cleaner. - Never use `typedef`; always write `using T = X` in favor of `typedef X T`.
- Use `typename` only when referring to dependent names.
- Keywords are always followed by a whitespace: `if (...)`, `template <...>`, - Keywords are always followed by a whitespace: `if (...)`, `template <...>`,
`while (...)`, etc. `while (...)`, etc.
- Always use `{}` for bodies of control structures such as `if` or `while`, - Leave a whitespace after `!` to make negations easily recognizable:
even for bodies consiting only of a single statement.
```cpp
if (! sunny())
stay_home();
else
go_outside();
```
- Opening braces belong to the same line: - Opening braces belong to the same line:
```cpp ```cpp
if (my_condition) { void foo() {
my_fun(); // ...
} else {
my_other_fun();
} }
``` ```
...@@ -240,54 +232,75 @@ General rules ...@@ -240,54 +232,75 @@ General rules
libraries, other libraries, (your) CAF headers: libraries, other libraries, (your) CAF headers:
```cpp ```cpp
// some .hpp file
#include <sys/types.h> #include <sys/types.h>
#include <vector> #include <vector>
#include "some/other/library.hpp" #include "3rd/party.h"
#include "caf/fwd.hpp"
```
CAF includes should always be in doublequotes, whereas system-wide includes
in angle brackets. In a `.cpp` file, the implemented header always comes first
and the header `caf/config.hpp` can be included second if you need
platform-dependent headers:
```cpp
// example.cpp
#include "caf/example.hpp" // header related to this .cpp file
#include "caf/config.hpp"
#ifdef CAF_WINDOWS
#include <windows.h>
#else
#include <sys/socket.h>
#endif
#include "caf/example/myclass.hpp" #include <algorithm>
#include "some/other/library.h"
#include "caf/actor.hpp"
``` ```
- When declaring a function, the order of parameters is: outputs, then inputs. - When declaring a function, the order of parameters is: outputs, then inputs.
This follows the parameter order from the STL. This follows the parameter order from the STL.
- Never use C-style casts.
- Protect single-argument constructors with `explicit` to avoid implicit conversions. - Protect single-argument constructors with `explicit` to avoid implicit conversions.
Naming Naming
------ ------
- Class names, constants, and function names are all-lowercase with underscores. - All names except macros and template parameters should be
lower case and delimited by underscores.
- Template parameter names should be written in CamelCase.
- Types and variables should be nouns, while functions performing an action - Types and variables should be nouns, while functions performing an action
should be "command" verbs. Classes used to implement metaprogramming should be "command" verbs. Classes used to implement metaprogramming
functions also should use verbs, e.g., `remove_const`. functions also should use verbs, e.g., `remove_const`.
- Member variables use the prefix `m_`. - Private and protected member variables use the suffix `_` while getter *and* setter
functions use the name without suffix:
- Thread-local variables use the prefix `t_`.
- Static, non-const variables are declared in the anonymous namespace
and use the prefix `s_`.
- Template parameter names use CamelCase.
- Getter and setter use the name of the member without the `m_` prefix:
```cpp ```cpp
class some_fun { class person {
public: public:
// ... const std::string& name() const {
int value() const { return name_
return m_value;
} }
void value(int new_value) {
m_value = new_value; void name(const std::string& new_name) {
name_ = new_name;
} }
private: private:
int m_value; std::string name_;
}; };
``` ```
...@@ -339,11 +352,11 @@ Breaking Statements ...@@ -339,11 +352,11 @@ Breaking Statements
```cpp ```cpp
my_class::my_class() my_class::my_class()
: my_base_class(some_function()), : my_base_class(some_function()),
m_greeting("Hello there! This is my_class!"), greeting_("Hello there! This is my_class!"),
m_some_bool_flag(false) { some_bool_flag_(false) {
// ok // ok
} }
other_class::other_class() : m_name("tommy"), m_buddy("michael") { other_class::other_class() : name_("tommy"), buddy_("michael") {
// ok // ok
} }
``` ```
...@@ -413,14 +426,6 @@ extra rules for formatting metaprogramming code. ...@@ -413,14 +426,6 @@ extra rules for formatting metaprogramming code.
``` ```
Rvalue References
-----------------
- Use rvalue references whenever it makes sense.
- Write move constructors and assignment operators if possible.
Preprocessor Macros Preprocessor Macros
------------------- -------------------
...@@ -428,3 +433,17 @@ Preprocessor Macros ...@@ -428,3 +433,17 @@ Preprocessor Macros
functions or proper constants. functions or proper constants.
- Macro names use the form `CAF_<COMPONENT>_<NAME>`. - Macro names use the form `CAF_<COMPONENT>_<NAME>`.
Comments
--------
- Doxygen comments start with `///`.
- Use Markdown instead of Doxygen formatters.
- Use `@cmd` rather than `\cmd`.
- Use `//` to define basic comments that should not be
swallowed by Doxygen.
...@@ -191,7 +191,7 @@ int main(int argc, char** argv) { ...@@ -191,7 +191,7 @@ int main(int argc, char** argv) {
{"port,p", "set port", port}, {"port,p", "set port", port},
{"host,H", "set host (client mode only"} {"host,H", "set host (client mode only"}
}); });
if (!res.error.empty()) { if (! res.error.empty()) {
cerr << res.error << endl; cerr << res.error << endl;
return 1; return 1;
} }
...@@ -199,7 +199,7 @@ int main(int argc, char** argv) { ...@@ -199,7 +199,7 @@ int main(int argc, char** argv) {
cout << res.helptext << endl; cout << res.helptext << endl;
return 0; return 0;
} }
if (!res.remainder.empty()) { if (! res.remainder.empty()) {
// not all CLI arguments could be consumed // not all CLI arguments could be consumed
cerr << "*** too many arguments" << endl << res.helptext << endl; cerr << "*** too many arguments" << endl << res.helptext << endl;
return 1; return 1;
......
...@@ -76,7 +76,7 @@ int main(int argc, const char** argv) { ...@@ -76,7 +76,7 @@ int main(int argc, const char** argv) {
auto res = message_builder(argv + 1, argv + argc).extract_opts({ auto res = message_builder(argv + 1, argv + argc).extract_opts({
{"port,p", "set port", port}, {"port,p", "set port", port},
}); });
if (!res.error.empty()) { if (! res.error.empty()) {
cerr << res.error << endl; cerr << res.error << endl;
return 1; return 1;
} }
...@@ -84,7 +84,7 @@ int main(int argc, const char** argv) { ...@@ -84,7 +84,7 @@ int main(int argc, const char** argv) {
cout << res.helptext << endl; cout << res.helptext << endl;
return 0; return 0;
} }
if (!res.remainder.empty()) { if (! res.remainder.empty()) {
// not all CLI arguments could be consumed // not all CLI arguments could be consumed
cerr << "*** too many arguments" << endl << res.helptext << endl; cerr << "*** too many arguments" << endl << res.helptext << endl;
return 1; return 1;
......
...@@ -99,31 +99,31 @@ constexpr int max_req_interval = 300; ...@@ -99,31 +99,31 @@ constexpr int max_req_interval = 300;
// provides print utility and each base_actor has a parent // provides print utility and each base_actor has a parent
class base_actor : public event_based_actor { class base_actor : public event_based_actor {
protected: protected:
base_actor(actor parent, std::string name, std::string color_code) base_actor(actor parent, std::string name, std::string color_code)
: m_parent(std::move(parent)), : parent_(std::move(parent)),
m_name(std::move(name)), name_(std::move(name)),
m_color(std::move(color_code)), color_(std::move(color_code)),
m_out(this) { out_(this) {
// nop // nop
} }
~base_actor(); ~base_actor();
inline actor_ostream& print() { inline actor_ostream& print() {
return m_out << m_color << m_name << " (id = " << id() << "): "; return out_ << color_ << name_ << " (id = " << id() << "): ";
} }
void on_exit() { void on_exit() {
print() << "on_exit" << color::reset_endl; print() << "on_exit" << color::reset_endl;
} }
actor m_parent; actor parent_;
private: private:
std::string m_name; std::string name_;
std::string m_color; std::string color_;
actor_ostream m_out; actor_ostream out_;
}; };
base_actor::~base_actor() { base_actor::~base_actor() {
...@@ -132,7 +132,7 @@ base_actor::~base_actor() { ...@@ -132,7 +132,7 @@ base_actor::~base_actor() {
// encapsulates an HTTP request // encapsulates an HTTP request
class client_job : public base_actor { class client_job : public base_actor {
public: public:
explicit client_job(actor parent) explicit client_job(actor parent)
: base_actor(std::move(parent), "client_job", color::blue) { : base_actor(std::move(parent), "client_job", color::blue) {
// nop // nop
...@@ -140,10 +140,10 @@ class client_job : public base_actor { ...@@ -140,10 +140,10 @@ class client_job : public base_actor {
~client_job(); ~client_job();
protected: protected:
behavior make_behavior() override { behavior make_behavior() override {
print() << "init" << color::reset_endl; print() << "init" << color::reset_endl;
send(m_parent, read_atom::value, "http://www.example.com/index.html", send(parent_, read_atom::value, "http://www.example.com/index.html",
uint64_t{0}, uint64_t{4095}); uint64_t{0}, uint64_t{4095});
return { return {
[=](reply_atom, const buffer_type& buf) { [=](reply_atom, const buffer_type& buf) {
...@@ -165,46 +165,46 @@ client_job::~client_job() { ...@@ -165,46 +165,46 @@ client_job::~client_job() {
// spawns HTTP requests // spawns HTTP requests
class client : public base_actor { class client : public base_actor {
public: public:
explicit client(const actor& parent) explicit client(const actor& parent)
: base_actor(parent, "client", color::green), : base_actor(parent, "client", color::green),
m_count(0), count_(0),
m_re(m_rd()), re_(rd_()),
m_dist(min_req_interval, max_req_interval) { dist_(min_req_interval, max_req_interval) {
// nop // nop
} }
~client(); ~client();
protected: protected:
behavior make_behavior() override { behavior make_behavior() override {
using std::chrono::milliseconds; using std::chrono::milliseconds;
link_to(m_parent); link_to(parent_);
print() << "init" << color::reset_endl; print() << "init" << color::reset_endl;
// start 'loop' // start 'loop'
send(this, next_atom::value); send(this, next_atom::value);
return ( return (
[=](next_atom) { [=](next_atom) {
print() << "spawn new client_job (nr. " print() << "spawn new client_job (nr. "
<< ++m_count << ++count_
<< ")" << ")"
<< color::reset_endl; << color::reset_endl;
// client_job will use IO // client_job will use IO
// and should thus be spawned in a separate thread // and should thus be spawned in a separate thread
spawn<client_job, detached+linked>(m_parent); spawn<client_job, detached+linked>(parent_);
// compute random delay until next job is launched // compute random delay until next job is launched
auto delay = m_dist(m_re); auto delay = dist_(re_);
delayed_send(this, milliseconds(delay), next_atom::value); delayed_send(this, milliseconds(delay), next_atom::value);
} }
); );
} }
private: private:
size_t m_count; size_t count_;
std::random_device m_rd; std::random_device rd_;
std::default_random_engine m_re; std::default_random_engine re_;
std::uniform_int_distribution<int> m_dist; std::uniform_int_distribution<int> dist_;
}; };
client::~client() { client::~client() {
...@@ -213,45 +213,45 @@ client::~client() { ...@@ -213,45 +213,45 @@ client::~client() {
// manages a CURL session // manages a CURL session
class curl_worker : public base_actor { class curl_worker : public base_actor {
public: public:
explicit curl_worker(const actor& parent) explicit curl_worker(const actor& parent)
: base_actor(parent, "curl_worker", color::yellow), : base_actor(parent, "curl_worker", color::yellow),
m_curl(nullptr) { curl_(nullptr) {
// nop // nop
} }
~curl_worker(); ~curl_worker();
protected: protected:
behavior make_behavior() override { behavior make_behavior() override {
print() << "init" << color::reset_endl; print() << "init" << color::reset_endl;
m_curl = curl_easy_init(); curl_ = curl_easy_init();
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, &curl_worker::cb); curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, &curl_worker::cb);
curl_easy_setopt(m_curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl_, CURLOPT_NOSIGNAL, 1);
return ( return (
[=](read_atom, const std::string& fname, uint64_t offset, uint64_t range) [=](read_atom, const std::string& fname, uint64_t offset, uint64_t range)
-> message { -> message {
print() << "read" << color::reset_endl; print() << "read" << color::reset_endl;
for (;;) { for (;;) {
m_buf.clear(); buf_.clear();
// set URL // set URL
curl_easy_setopt(m_curl, CURLOPT_URL, fname.c_str()); curl_easy_setopt(curl_, CURLOPT_URL, fname.c_str());
// set range // set range
std::ostringstream oss; std::ostringstream oss;
oss << offset << "-" << range; oss << offset << "-" << range;
curl_easy_setopt(m_curl, CURLOPT_RANGE, oss.str().c_str()); curl_easy_setopt(curl_, CURLOPT_RANGE, oss.str().c_str());
// set curl callback // set curl callback
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, curl_easy_setopt(curl_, CURLOPT_WRITEDATA,
reinterpret_cast<void*>(this)); reinterpret_cast<void*>(this));
// launch file transfer // launch file transfer
auto res = curl_easy_perform(m_curl); auto res = curl_easy_perform(curl_);
if (res != CURLE_OK) { if (res != CURLE_OK) {
print() << "curl_easy_perform() failed: " print() << "curl_easy_perform() failed: "
<< curl_easy_strerror(res) << curl_easy_strerror(res)
<< color::reset_endl; << color::reset_endl;
} else { } else {
long hc = 0; // http return code long hc = 0; // http return code
curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &hc); curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, &hc);
switch (hc) { switch (hc) {
default: default:
print() << "http error: download failed with " print() << "http error: download failed with "
...@@ -262,13 +262,13 @@ class curl_worker : public base_actor { ...@@ -262,13 +262,13 @@ class curl_worker : public base_actor {
case 200: // ok case 200: // ok
case 206: // partial content case 206: // partial content
print() << "received " print() << "received "
<< m_buf.size() << buf_.size()
<< " bytes with 'HTTP RETURN CODE': " << " bytes with 'HTTP RETURN CODE': "
<< hc << hc
<< color::reset_endl; << color::reset_endl;
// tell parent that this worker is done // tell parent that this worker is done
send(m_parent, finished_atom::value); send(parent_, finished_atom::value);
return make_message(reply_atom::value, m_buf); return make_message(reply_atom::value, buf_);
case 404: // file does not exist case 404: // file does not exist
print() << "http error: download failed with " print() << "http error: download failed with "
<< "'HTTP RETURN CODE': 404 (file does " << "'HTTP RETURN CODE': 404 (file does "
...@@ -284,22 +284,22 @@ class curl_worker : public base_actor { ...@@ -284,22 +284,22 @@ class curl_worker : public base_actor {
} }
void on_exit() { void on_exit() {
curl_easy_cleanup(m_curl); curl_easy_cleanup(curl_);
print() << "on_exit" << color::reset_endl; print() << "on_exit" << color::reset_endl;
} }
private: private:
static size_t cb(void* data, size_t bsize, size_t nmemb, void* userp) { static size_t cb(void* data, size_t bsize, size_t nmemb, void* userp) {
size_t size = bsize * nmemb; size_t size = bsize * nmemb;
auto& buf = reinterpret_cast<curl_worker*>(userp)->m_buf; auto& buf = reinterpret_cast<curl_worker*>(userp)->buf_;
auto first = reinterpret_cast<char*>(data); auto first = reinterpret_cast<char*>(data);
auto last = first + bsize; auto last = first + bsize;
buf.insert(buf.end(), first, last); buf.insert(buf.end(), first, last);
return size; return size;
} }
CURL* m_curl; CURL* curl_;
buffer_type m_buf; buffer_type buf_;
}; };
curl_worker::~curl_worker() { curl_worker::~curl_worker() {
...@@ -308,39 +308,39 @@ curl_worker::~curl_worker() { ...@@ -308,39 +308,39 @@ curl_worker::~curl_worker() {
// manages {num_curl_workers} workers with a round-robin protocol // manages {num_curl_workers} workers with a round-robin protocol
class curl_master : public base_actor { class curl_master : public base_actor {
public: public:
curl_master() : base_actor(invalid_actor, "curl_master", color::magenta) { curl_master() : base_actor(invalid_actor, "curl_master", color::magenta) {
// nop // nop
} }
~curl_master(); ~curl_master();
protected: protected:
behavior make_behavior() override { behavior make_behavior() override {
print() << "init" << color::reset_endl; print() << "init" << color::reset_endl;
// spawn workers // spawn workers
for(size_t i = 0; i < num_curl_workers; ++i) { for(size_t i = 0; i < num_curl_workers; ++i) {
m_idle_worker.push_back(spawn<curl_worker, detached+linked>(this)); idle_worker_.push_back(spawn<curl_worker, detached+linked>(this));
} }
auto worker_finished = [=] { auto worker_finished = [=] {
auto sender = current_sender(); auto sender = current_sender();
auto i = std::find(m_busy_worker.begin(), m_busy_worker.end(), sender); auto i = std::find(busy_worker_.begin(), busy_worker_.end(), sender);
m_idle_worker.push_back(*i); idle_worker_.push_back(*i);
m_busy_worker.erase(i); busy_worker_.erase(i);
print() << "worker is done" << color::reset_endl; print() << "worker is done" << color::reset_endl;
}; };
print() << "spawned " << m_idle_worker.size() print() << "spawned " << idle_worker_.size()
<< " worker(s)" << color::reset_endl; << " worker(s)" << color::reset_endl;
return { return {
[=](read_atom, const std::string&, uint64_t, uint64_t) { [=](read_atom, const std::string&, uint64_t, uint64_t) {
print() << "received {'read'}" << color::reset_endl; print() << "received {'read'}" << color::reset_endl;
// forward job to an idle worker // forward job to an idle worker
actor worker = m_idle_worker.back(); actor worker = idle_worker_.back();
m_idle_worker.pop_back(); idle_worker_.pop_back();
m_busy_worker.push_back(worker); busy_worker_.push_back(worker);
forward_to(worker); forward_to(worker);
print() << m_busy_worker.size() << " active jobs" << color::reset_endl; print() << busy_worker_.size() << " active jobs" << color::reset_endl;
if (m_idle_worker.empty()) { if (idle_worker_.empty()) {
// wait until at least one worker finished its job // wait until at least one worker finished its job
become ( become (
keep_behavior, keep_behavior,
...@@ -357,9 +357,9 @@ class curl_master : public base_actor { ...@@ -357,9 +357,9 @@ class curl_master : public base_actor {
}; };
} }
private: private:
std::vector<actor> m_idle_worker; std::vector<actor> idle_worker_;
std::vector<actor> m_busy_worker; std::vector<actor> busy_worker_;
}; };
curl_master::~curl_master() { curl_master::~curl_master() {
...@@ -391,7 +391,7 @@ int main() { ...@@ -391,7 +391,7 @@ int main() {
auto master = self->spawn<curl_master, detached>(); auto master = self->spawn<curl_master, detached>();
self->spawn<client, detached>(master); self->spawn<client, detached>(master);
// poll CTRL+C flag every second // poll CTRL+C flag every second
while (!shutdown_flag) { while (! shutdown_flag) {
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
} }
aout(self) << color::cyan << "received CTRL+C" << color::reset_endl; aout(self) << color::cyan << "received CTRL+C" << color::reset_endl;
......
...@@ -95,7 +95,7 @@ chopstick::behavior_type taken_chopstick(chopstick::pointer self, ...@@ -95,7 +95,7 @@ chopstick::behavior_type taken_chopstick(chopstick::pointer self,
*/ */
class philosopher : public event_based_actor { class philosopher : public event_based_actor {
public: public:
philosopher(const std::string& n, const chopstick& l, const chopstick& r) philosopher(const std::string& n, const chopstick& l, const chopstick& r)
: name(n), : name(n),
left(l), left(l),
...@@ -158,7 +158,7 @@ class philosopher : public event_based_actor { ...@@ -158,7 +158,7 @@ class philosopher : public event_based_actor {
); );
} }
protected: protected:
behavior make_behavior() override { behavior make_behavior() override {
// start thinking // start thinking
send(this, think_atom::value); send(this, think_atom::value);
...@@ -172,7 +172,7 @@ class philosopher : public event_based_actor { ...@@ -172,7 +172,7 @@ class philosopher : public event_based_actor {
); );
} }
private: private:
std::string name; // the name of this philosopher std::string name; // the name of this philosopher
chopstick left; // left chopstick chopstick left; // left chopstick
chopstick right; // right chopstick chopstick right; // right chopstick
......
...@@ -32,7 +32,7 @@ calculator_type::behavior_type typed_calculator(calculator_type::pointer) { ...@@ -32,7 +32,7 @@ calculator_type::behavior_type typed_calculator(calculator_type::pointer) {
} }
class typed_calculator_class : public calculator_type::base { class typed_calculator_class : public calculator_type::base {
protected: protected:
behavior_type make_behavior() override { behavior_type make_behavior() override {
return { return {
[](plus_atom, int x, int y) { [](plus_atom, int x, int y) {
......
...@@ -15,24 +15,24 @@ using namespace std; ...@@ -15,24 +15,24 @@ using namespace std;
using namespace caf; using namespace caf;
ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f) ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f)
: super(parent, f), m_input(nullptr), m_output(nullptr) { : super(parent, f), input_(nullptr), output_(nullptr) {
set_message_handler ([=](local_actor* self) -> message_handler { set_message_handler ([=](local_actor* self) -> message_handler {
return { return {
on(atom("join"), arg_match) >> [=](const group& what) { on(atom("join"), arg_match) >> [=](const group& what) {
if (m_chatroom) { if (chatroom_) {
self->send(m_chatroom, m_name + " has left the chatroom"); self->send(chatroom_, name_ + " has left the chatroom");
self->leave(m_chatroom); self->leave(chatroom_);
} }
self->join(what); self->join(what);
print(("*** joined " + to_string(what)).c_str()); print(("*** joined " + to_string(what)).c_str());
m_chatroom = what; chatroom_ = what;
self->send(what, m_name + " has entered the chatroom"); self->send(what, name_ + " has entered the chatroom");
}, },
on(atom("setName"), arg_match) >> [=](string& name) { on(atom("setName"), arg_match) >> [=](string& name) {
self->send(m_chatroom, m_name + " is now known as " + name); self->send(chatroom_, name_ + " is now known as " + name);
m_name = std::move(name); name_ = std::move(name);
print("*** changed name to " print("*** changed name to "
+ QString::fromUtf8(m_name.c_str())); + QString::fromUtf8(name_.c_str()));
}, },
on(atom("quit")) >> [=] { on(atom("quit")) >> [=] {
close(); // close widget close(); // close widget
...@@ -81,23 +81,23 @@ void ChatWidget::sendChatMessage() { ...@@ -81,23 +81,23 @@ void ChatWidget::sendChatMessage() {
}); });
return; return;
} }
if (m_name.empty()) { if (name_.empty()) {
print("*** please set a name before sending messages"); print("*** please set a name before sending messages");
return; return;
} }
if (!m_chatroom) { if (! chatroom_) {
print("*** no one is listening... please join a group"); print("*** no one is listening... please join a group");
return; return;
} }
string msg = m_name; string msg = name_;
msg += ": "; msg += ": ";
msg += line.toUtf8().constData(); msg += line.toUtf8().constData();
print("<you>: " + input()->text()); print("<you>: " + input()->text());
send_as(as_actor(), m_chatroom, std::move(msg)); send_as(as_actor(), chatroom_, std::move(msg));
} }
void ChatWidget::joinGroup() { void ChatWidget::joinGroup() {
if (m_name.empty()) { if (name_.empty()) {
QMessageBox::information(this, QMessageBox::information(this,
"No Name, No Chat", "No Name, No Chat",
"Please set a name first."); "Please set a name first.");
...@@ -126,7 +126,7 @@ void ChatWidget::joinGroup() { ...@@ -126,7 +126,7 @@ void ChatWidget::joinGroup() {
void ChatWidget::changeName() { void ChatWidget::changeName() {
auto name = QInputDialog::getText(this, "Change Name", "Please enter a new name"); auto name = QInputDialog::getText(this, "Change Name", "Please enter a new name");
if (!name.isEmpty()) { if (! name.isEmpty()) {
send_as(as_actor(), as_actor(), atom("setName"), name.toUtf8().constData()); send_as(as_actor(), as_actor(), atom("setName"), name.toUtf8().constData());
} }
} }
...@@ -15,7 +15,7 @@ class ChatWidget : public caf::mixin::actor_widget<QWidget> { ...@@ -15,7 +15,7 @@ class ChatWidget : public caf::mixin::actor_widget<QWidget> {
typedef caf::mixin::actor_widget<QWidget> super; typedef caf::mixin::actor_widget<QWidget> super;
public: public:
ChatWidget(QWidget* parent = nullptr, Qt::WindowFlags f = 0); ChatWidget(QWidget* parent = nullptr, Qt::WindowFlags f = 0);
...@@ -25,7 +25,7 @@ class ChatWidget : public caf::mixin::actor_widget<QWidget> { ...@@ -25,7 +25,7 @@ class ChatWidget : public caf::mixin::actor_widget<QWidget> {
void joinGroup(); void joinGroup();
void changeName(); void changeName();
private: private:
template<typename T> template<typename T>
T* get(T*& member, const char* name) { T* get(T*& member, const char* name) {
...@@ -39,20 +39,20 @@ class ChatWidget : public caf::mixin::actor_widget<QWidget> { ...@@ -39,20 +39,20 @@ class ChatWidget : public caf::mixin::actor_widget<QWidget> {
} }
inline QLineEdit* input() { inline QLineEdit* input() {
return get(m_input, "input"); return get(input_, "input");
} }
inline QTextEdit* output() { inline QTextEdit* output() {
return get(m_output, "output"); return get(output_, "output");
} }
inline void print(const QString& what) { inline void print(const QString& what) {
output()->append(what); output()->append(what);
} }
QLineEdit* m_input; QLineEdit* input_;
QTextEdit* m_output; QTextEdit* output_;
std::string m_name; std::string name_;
caf::group m_chatroom; caf::group chatroom_;
}; };
...@@ -35,11 +35,11 @@ int main(int argc, char** argv) { ...@@ -35,11 +35,11 @@ int main(int argc, char** argv) {
{"name,n", "set chat name", name}, {"name,n", "set chat name", name},
{"group,g", "join chat group", group_id} {"group,g", "join chat group", group_id}
}); });
if (!res.error.empty()) { if (! res.error.empty()) {
cerr << res.error << endl; cerr << res.error << endl;
return 1; return 1;
} }
if (!res.remainder.empty()) { if (! res.remainder.empty()) {
std::cerr << res.helptext << std::endl; std::cerr << res.helptext << std::endl;
return 1; return 1;
} }
...@@ -49,7 +49,7 @@ int main(int argc, char** argv) { ...@@ -49,7 +49,7 @@ int main(int argc, char** argv) {
} }
group gptr; group gptr;
// evaluate group parameter // evaluate group parameter
if (!group_id.empty()) { if (! group_id.empty()) {
auto p = group_id.find(':'); auto p = group_id.find(':');
if (p == std::string::npos) { if (p == std::string::npos) {
cerr << "*** error parsing argument " << group_id cerr << "*** error parsing argument " << group_id
...@@ -70,7 +70,7 @@ int main(int argc, char** argv) { ...@@ -70,7 +70,7 @@ int main(int argc, char** argv) {
Ui::ChatWindow helper; Ui::ChatWindow helper;
helper.setupUi(&mw); helper.setupUi(&mw);
auto client = helper.chatwidget->as_actor(); auto client = helper.chatwidget->as_actor();
if (!name.empty()) { if (! name.empty()) {
send_as(client, client, atom("setName"), move(name)); send_as(client, client, atom("setName"), move(name));
} }
if (gptr) { if (gptr) {
......
...@@ -51,10 +51,10 @@ behavior calculator() { ...@@ -51,10 +51,10 @@ behavior calculator() {
} }
class client_impl : public event_based_actor { class client_impl : public event_based_actor {
public: public:
client_impl(string hostaddr, uint16_t port) client_impl(string hostaddr, uint16_t port)
: m_host(std::move(hostaddr)), : host_(std::move(hostaddr)),
m_port(port) { port_(port) {
// nop // nop
} }
...@@ -64,12 +64,12 @@ class client_impl : public event_based_actor { ...@@ -64,12 +64,12 @@ class client_impl : public event_based_actor {
return {}; return {};
} }
private: private:
void sync_send_task(atom_value op, int lhs, int rhs) { void sync_send_task(atom_value op, int lhs, int rhs) {
on_sync_failure([=] { on_sync_failure([=] {
aout(this) << "*** sync_failure!" << endl; aout(this) << "*** sync_failure!" << endl;
}); });
sync_send(m_server, op, lhs, rhs).then( sync_send(server_, op, lhs, rhs).then(
[=](result_atom, int result) { [=](result_atom, int result) {
aout(this) << lhs << (op == plus_atom::value ? " + " : " - ") aout(this) << lhs << (op == plus_atom::value ? " + " : " - ")
<< rhs << " = " << result << endl; << rhs << " = " << result << endl;
...@@ -95,8 +95,8 @@ class client_impl : public event_based_actor { ...@@ -95,8 +95,8 @@ class client_impl : public event_based_actor {
[=](rebind_atom, string& nhost, uint16_t nport) { [=](rebind_atom, string& nhost, uint16_t nport) {
aout(this) << "*** rebind to " << nhost << ":" << nport << endl; aout(this) << "*** rebind to " << nhost << ":" << nport << endl;
using std::swap; using std::swap;
swap(m_host, nhost); swap(host_, nhost);
swap(m_port, nport); swap(port_, nport);
become(keep_behavior, reconnecting()); become(keep_behavior, reconnecting());
} }
}; };
...@@ -105,11 +105,11 @@ class client_impl : public event_based_actor { ...@@ -105,11 +105,11 @@ class client_impl : public event_based_actor {
behavior reconnecting(std::function<void()> continuation = nullptr) { behavior reconnecting(std::function<void()> continuation = nullptr) {
using std::chrono::seconds; using std::chrono::seconds;
auto mm = io::get_middleman_actor(); auto mm = io::get_middleman_actor();
send(mm, get_atom::value, m_host, m_port); send(mm, get_atom::value, host_, port_);
return { return {
[=](ok_atom, const actor_addr& new_server) { [=](ok_atom, const actor_addr& new_server) {
aout(this) << "*** connection succeeded, awaiting tasks" << endl; aout(this) << "*** connection succeeded, awaiting tasks" << endl;
m_server = actor_cast<actor>(new_server); server_ = actor_cast<actor>(new_server);
// return to previous behavior // return to previous behavior
if (continuation) { if (continuation) {
continuation(); continuation();
...@@ -117,24 +117,24 @@ class client_impl : public event_based_actor { ...@@ -117,24 +117,24 @@ class client_impl : public event_based_actor {
unbecome(); unbecome();
}, },
[=](error_atom, const string& errstr) { [=](error_atom, const string& errstr) {
aout(this) << "*** could not connect to " << m_host aout(this) << "*** could not connect to " << host_
<< " at port " << m_port << " at port " << port_
<< ": " << errstr << ": " << errstr
<< " [try again in 3s]" << " [try again in 3s]"
<< endl; << endl;
delayed_send(mm, seconds(3), get_atom::value, m_host, m_port); delayed_send(mm, seconds(3), get_atom::value, host_, port_);
}, },
[=](rebind_atom, string& nhost, uint16_t nport) { [=](rebind_atom, string& nhost, uint16_t nport) {
aout(this) << "*** rebind to " << nhost << ":" << nport << endl; aout(this) << "*** rebind to " << nhost << ":" << nport << endl;
using std::swap; using std::swap;
swap(m_host, nhost); swap(host_, nhost);
swap(m_port, nport); swap(port_, nport);
// await pending ok/error message first, then send new request to MM // await pending ok/error message first, then send new request to MM
become( become(
keep_behavior, keep_behavior,
(on<ok_atom, actor_addr>() || on<error_atom, string>()) >> [=] { (on<ok_atom, actor_addr>() || on<error_atom, string>()) >> [=] {
unbecome(); unbecome();
send(mm, get_atom::value, m_host, m_port); send(mm, get_atom::value, host_, port_);
} }
); );
}, },
...@@ -143,14 +143,14 @@ class client_impl : public event_based_actor { ...@@ -143,14 +143,14 @@ class client_impl : public event_based_actor {
}; };
} }
actor m_server; actor server_;
string m_host; string host_;
uint16_t m_port; uint16_t port_;
}; };
// removes leading and trailing whitespaces // removes leading and trailing whitespaces
string trim(std::string s) { string trim(std::string s) {
auto not_space = [](char c) { return !isspace(c); }; auto not_space = [](char c) { return ! isspace(c); };
// trim left // trim left
s.erase(s.begin(), find_if(s.begin(), s.end(), not_space)); s.erase(s.begin(), find_if(s.begin(), s.end(), not_space));
// trim right // trim right
...@@ -222,7 +222,7 @@ void client_repl(string host, uint16_t port) { ...@@ -222,7 +222,7 @@ void client_repl(string host, uint16_t port) {
}; };
// read next line, split it, and feed to the eval handler // read next line, split it, and feed to the eval handler
string line; string line;
while (!done && std::getline(std::cin, line)) { while (! done && std::getline(std::cin, line)) {
line = trim(std::move(line)); // ignore leading and trailing whitespaces line = trim(std::move(line)); // ignore leading and trailing whitespaces
std::vector<string> words; std::vector<string> words;
split(words, line, is_any_of(" "), token_compress_on); split(words, line, is_any_of(" "), token_compress_on);
...@@ -241,7 +241,7 @@ int main(int argc, char** argv) { ...@@ -241,7 +241,7 @@ int main(int argc, char** argv) {
{"server,s", "run in server mode"}, {"server,s", "run in server mode"},
{"client,c", "run in client mode"} {"client,c", "run in client mode"}
}); });
if (!res.error.empty()) { if (! res.error.empty()) {
cerr << res.error << endl; cerr << res.error << endl;
return 1; return 1;
} }
...@@ -249,7 +249,7 @@ int main(int argc, char** argv) { ...@@ -249,7 +249,7 @@ int main(int argc, char** argv) {
cout << res.helptext << endl; cout << res.helptext << endl;
return 0; return 0;
} }
if (!res.remainder.empty()) { if (! res.remainder.empty()) {
// not all CLI arguments could be consumed // not all CLI arguments could be consumed
cerr << "*** invalid command line options" << endl << res.helptext << endl; cerr << "*** invalid command line options" << endl << res.helptext << endl;
return 1; return 1;
...@@ -263,7 +263,7 @@ int main(int argc, char** argv) { ...@@ -263,7 +263,7 @@ int main(int argc, char** argv) {
} }
return 1; return 1;
} }
if (!is_server && port == 0) { if (! is_server && port == 0) {
cerr << "*** no port to server specified" << endl; cerr << "*** no port to server specified" << endl;
return 1; return 1;
} }
......
...@@ -71,11 +71,11 @@ int main(int argc, char** argv) { ...@@ -71,11 +71,11 @@ int main(int argc, char** argv) {
{"name,n", "set name", name}, {"name,n", "set name", name},
{"group,g", "join group", group_id} {"group,g", "join group", group_id}
}); });
if (!res.error.empty()) { if (! res.error.empty()) {
cerr << res.error << endl; cerr << res.error << endl;
return 1; return 1;
} }
if (!res.remainder.empty()) { if (! res.remainder.empty()) {
std::cout << res.helptext << std::endl; std::cout << res.helptext << std::endl;
return 1; return 1;
} }
...@@ -85,14 +85,14 @@ int main(int argc, char** argv) { ...@@ -85,14 +85,14 @@ int main(int argc, char** argv) {
} }
while (name.empty()) { while (name.empty()) {
cout << "please enter your name: " << flush; cout << "please enter your name: " << flush;
if (!getline(cin, name)) { if (! getline(cin, name)) {
cerr << "*** no name given... terminating" << endl; cerr << "*** no name given... terminating" << endl;
return 1; return 1;
} }
} }
auto client_actor = spawn(client, name); auto client_actor = spawn(client, name);
// evaluate group parameters // evaluate group parameters
if (!group_id.empty()) { if (! group_id.empty()) {
auto p = group_id.find(':'); auto p = group_id.find(':');
if (p == std::string::npos) { if (p == std::string::npos) {
cerr << "*** error parsing argument " << group_id cerr << "*** error parsing argument " << group_id
...@@ -148,7 +148,7 @@ int main(int argc, char** argv) { ...@@ -148,7 +148,7 @@ int main(int argc, char** argv) {
" /help print this text\n" << flush; " /help print this text\n" << flush;
}, },
others >> [&] { others >> [&] {
if (!i->str.empty()) { if (! i->str.empty()) {
anon_send(client_actor, broadcast_atom::value, i->str); anon_send(client_actor, broadcast_atom::value, i->str);
} }
} }
......
...@@ -23,7 +23,7 @@ int main(int argc, char** argv) { ...@@ -23,7 +23,7 @@ int main(int argc, char** argv) {
auto res = message_builder(argv + 1, argv + argc).extract_opts({ auto res = message_builder(argv + 1, argv + argc).extract_opts({
{"port,p", "set port", port} {"port,p", "set port", port}
}); });
if (!res.error.empty()) { if (! res.error.empty()) {
cerr << res.error << endl; cerr << res.error << endl;
return 1; return 1;
} }
...@@ -31,7 +31,7 @@ int main(int argc, char** argv) { ...@@ -31,7 +31,7 @@ int main(int argc, char** argv) {
cout << res.helptext << endl; cout << res.helptext << endl;
return 0; return 0;
} }
if (!res.remainder.empty()) { if (! res.remainder.empty()) {
// not all CLI arguments could be consumed // not all CLI arguments could be consumed
cerr << "*** too many arguments" << endl << res.helptext << endl; cerr << "*** too many arguments" << endl << res.helptext << endl;
return 1; return 1;
......
...@@ -12,24 +12,24 @@ using namespace caf; ...@@ -12,24 +12,24 @@ using namespace caf;
// a simple class using getter and setter member functions // a simple class using getter and setter member functions
class foo { class foo {
int m_a; int a_;
int m_b; int b_;
public: public:
foo(int a0 = 0, int b0 = 0) : m_a(a0), m_b(b0) { } foo(int a0 = 0, int b0 = 0) : a_(a0), b_(b0) { }
foo(const foo&) = default; foo(const foo&) = default;
foo& operator=(const foo&) = default; foo& operator=(const foo&) = default;
int a() const { return m_a; } int a() const { return a_; }
void set_a(int val) { m_a = val; } void set_a(int val) { a_ = val; }
int b() const { return m_b; } int b() const { return b_; }
void set_b(int val) { m_b = val; } void set_b(int val) { b_ = val; }
}; };
......
...@@ -12,26 +12,26 @@ using namespace caf; ...@@ -12,26 +12,26 @@ using namespace caf;
// a simple class using overloaded getter and setter member functions // a simple class using overloaded getter and setter member functions
class foo { class foo {
int m_a; int a_;
int m_b; int b_;
public: public:
foo() : m_a(0), m_b(0) { } foo() : a_(0), b_(0) { }
foo(int a0, int b0) : m_a(a0), m_b(b0) { } foo(int a0, int b0) : a_(a0), b_(b0) { }
foo(const foo&) = default; foo(const foo&) = default;
foo& operator=(const foo&) = default; foo& operator=(const foo&) = default;
int a() const { return m_a; } int a() const { return a_; }
void a(int val) { m_a = val; } void a(int val) { a_ = val; }
int b() const { return m_b; } int b() const { return b_; }
void b(int val) { m_b = val; } void b(int val) { b_ = val; }
}; };
......
...@@ -11,26 +11,26 @@ using namespace caf; ...@@ -11,26 +11,26 @@ using namespace caf;
// the foo class from example 3 // the foo class from example 3
class foo { class foo {
int m_a; int a_;
int m_b; int b_;
public: public:
foo() : m_a(0), m_b(0) { } foo() : a_(0), b_(0) { }
foo(int a0, int b0) : m_a(a0), m_b(b0) { } foo(int a0, int b0) : a_(a0), b_(b0) { }
foo(const foo&) = default; foo(const foo&) = default;
foo& operator=(const foo&) = default; foo& operator=(const foo&) = default;
int a() const { return m_a; } int a() const { return a_; }
void set_a(int val) { m_a = val; } void set_a(int val) { a_ = val; }
int b() const { return m_b; } int b() const { return b_; }
void set_b(int val) { m_b = val; } void set_b(int val) { b_ = val; }
}; };
...@@ -55,20 +55,20 @@ bool operator==(const bar& lhs, const bar& rhs) { ...@@ -55,20 +55,20 @@ bool operator==(const bar& lhs, const bar& rhs) {
// "worst case" class ... not a good software design at all ;) // "worst case" class ... not a good software design at all ;)
class baz { class baz {
foo m_f; foo f_;
public: public:
bar b; bar b;
// announce requires a default constructor // announce requires a default constructor
baz() = default; baz() = default;
inline baz(const foo& mf, const bar& mb) : m_f(mf), b(mb) { } inline baz(const foo& mf, const bar& mb) : f_(mf), b(mb) { }
const foo& f() const { return m_f; } const foo& f() const { return f_; }
void set_f(const foo& val) { m_f = val; } void set_f(const foo& val) { f_ = val; }
}; };
......
...@@ -87,12 +87,12 @@ bool operator==(const tree& lhs, const tree& rhs) { ...@@ -87,12 +87,12 @@ bool operator==(const tree& lhs, const tree& rhs) {
// - does have a copy constructor // - does have a copy constructor
// - does provide operator== // - does provide operator==
class tree_type_info : public detail::abstract_uniform_type_info<tree> { class tree_type_info : public detail::abstract_uniform_type_info<tree> {
public: public:
tree_type_info() : detail::abstract_uniform_type_info<tree>("tree") { tree_type_info() : detail::abstract_uniform_type_info<tree>("tree") {
// nop // nop
} }
protected: protected:
void serialize(const void* ptr, serializer* sink) const { void serialize(const void* ptr, serializer* sink) const {
// ptr is guaranteed to be a pointer of type tree // ptr is guaranteed to be a pointer of type tree
auto tree_ptr = reinterpret_cast<const tree*>(ptr); auto tree_ptr = reinterpret_cast<const tree*>(ptr);
...@@ -108,7 +108,7 @@ class tree_type_info : public detail::abstract_uniform_type_info<tree> { ...@@ -108,7 +108,7 @@ class tree_type_info : public detail::abstract_uniform_type_info<tree> {
deserialize_node(tree_ptr->root, source); deserialize_node(tree_ptr->root, source);
} }
private: private:
void serialize_node(const tree_node& node, serializer* sink) const { void serialize_node(const tree_node& node, serializer* sink) const {
// value, ... children ... // value, ... children ...
sink->write_value(node.value); sink->write_value(node.value);
......
...@@ -44,151 +44,107 @@ ...@@ -44,151 +44,107 @@
namespace caf { namespace caf {
/** /// A unique actor ID.
* A unique actor ID. /// @relates abstract_actor
* @relates abstract_actor
*/
using actor_id = uint32_t; using actor_id = uint32_t;
/** /// Denotes an ID that is never used by an actor.
* Denotes an ID that is never used by an actor.
*/
constexpr actor_id invalid_actor_id = 0; constexpr actor_id invalid_actor_id = 0;
using abstract_actor_ptr = intrusive_ptr<abstract_actor>; using abstract_actor_ptr = intrusive_ptr<abstract_actor>;
/** /// Base class for all actor implementations.
* Base class for all actor implementations.
*/
class abstract_actor : public abstract_channel { class abstract_actor : public abstract_channel {
public: public:
/** /// Attaches `ptr` to this actor. The actor will call `ptr->detach(...)` on
* Attaches `ptr` to this actor. The actor will call `ptr->detach(...)` on /// exit, or immediately if it already finished execution.
* exit, or immediately if it already finished execution.
*/
void attach(attachable_ptr ptr); void attach(attachable_ptr ptr);
/** /// Convenience function that attaches the functor `f` to this actor. The
* Convenience function that attaches the functor `f` to this actor. The /// actor executes `f()` on exit or immediatley if it is not running.
* actor executes `f()` on exit or immediatley if it is not running.
*/
template <class F> template <class F>
void attach_functor(F f) { void attach_functor(F f) {
attach(attachable_ptr{new detail::functor_attachable<F>(std::move(f))}); attach(attachable_ptr{new detail::functor_attachable<F>(std::move(f))});
} }
/** /// Returns the logical actor address.
* Returns the logical actor address.
*/
actor_addr address() const; actor_addr address() const;
/** /// Detaches the first attached object that matches `what`.
* Detaches the first attached object that matches `what`.
*/
size_t detach(const attachable::token& what); size_t detach(const attachable::token& what);
/** /// Links this actor to `whom`.
* Links this actor to `whom`.
*/
inline void link_to(const actor_addr& whom) { inline void link_to(const actor_addr& whom) {
link_impl(establish_link_op, whom); link_impl(establish_link_op, whom);
} }
/** /// Links this actor to `whom`.
* Links this actor to `whom`.
*/
template <class ActorHandle> template <class ActorHandle>
void link_to(const ActorHandle& whom) { void link_to(const ActorHandle& whom) {
link_to(whom.address()); link_to(whom.address());
} }
/** /// Unlinks this actor from `whom`.
* Unlinks this actor from `whom`.
*/
inline void unlink_from(const actor_addr& other) { inline void unlink_from(const actor_addr& other) {
link_impl(remove_link_op, other); link_impl(remove_link_op, other);
} }
/** /// Unlinks this actor from `whom`.
* Unlinks this actor from `whom`.
*/
template <class ActorHandle> template <class ActorHandle>
void unlink_from(const ActorHandle& other) { void unlink_from(const ActorHandle& other) {
unlink_from(other.address()); unlink_from(other.address());
} }
/** /// Establishes a link relation between this actor and `other`
* Establishes a link relation between this actor and `other` /// and returns whether the operation succeeded.
* and returns whether the operation succeeded.
*/
inline bool establish_backlink(const actor_addr& other) { inline bool establish_backlink(const actor_addr& other) {
return link_impl(establish_backlink_op, other); return link_impl(establish_backlink_op, other);
} }
/** /// Removes the link relation between this actor and `other`
* Removes the link relation between this actor and `other` /// and returns whether the operation succeeded.
* and returns whether the operation succeeded.
*/
inline bool remove_backlink(const actor_addr& other) { inline bool remove_backlink(const actor_addr& other) {
return link_impl(remove_backlink_op, other); return link_impl(remove_backlink_op, other);
} }
/** /// Returns the unique ID of this actor.
* Returns the unique ID of this actor.
*/
inline uint32_t id() const { inline uint32_t id() const {
return m_id; return id_;
} }
/** /// Returns the actor's exit reason or
* Returns the actor's exit reason or /// `exit_reason::not_exited` if it's still alive.
* `exit_reason::not_exited` if it's still alive.
*/
inline uint32_t exit_reason() const { inline uint32_t exit_reason() const {
return m_exit_reason; return exit_reason_;
} }
/** /// Returns the set of accepted messages types as strings or
* Returns the set of accepted messages types as strings or /// an empty set if this actor is untyped.
* an empty set if this actor is untyped.
*/
virtual std::set<std::string> message_types() const; virtual std::set<std::string> message_types() const;
/** /// Returns the execution unit currently used by this actor.
* Returns the execution unit currently used by this actor. /// @warning not thread safe
* @warning not thread safe
*/
inline execution_unit* host() const { inline execution_unit* host() const {
return m_host; return host_;
} }
/** /// Sets the execution unit for this actor.
* Sets the execution unit for this actor.
*/
inline void host(execution_unit* new_host) { inline void host(execution_unit* new_host) {
m_host = new_host; host_ = new_host;
} }
protected: protected:
/** /// Creates a non-proxy instance.
* Creates a non-proxy instance.
*/
abstract_actor(); abstract_actor();
/** /// Creates a proxy instance for a proxy running on `nid`.
* Creates a proxy instance for a proxy running on `nid`.
*/
abstract_actor(actor_id aid, node_id nid); abstract_actor(actor_id aid, node_id nid);
/** /// Called by the runtime system to perform cleanup actions for this actor.
* Called by the runtime system to perform cleanup actions for this actor. /// Subtypes should always call this member function when overriding it.
* Subtypes should always call this member function when overriding it.
*/
void cleanup(uint32_t reason); void cleanup(uint32_t reason);
/** /// Returns `exit_reason() != exit_reason::not_exited`.
* Returns `exit_reason() != exit_reason::not_exited`.
*/
inline bool exited() const { inline bool exited() const {
return exit_reason() != exit_reason::not_exited; return exit_reason() != exit_reason::not_exited;
} }
...@@ -197,8 +153,8 @@ class abstract_actor : public abstract_channel { ...@@ -197,8 +153,8 @@ class abstract_actor : public abstract_channel {
* here be dragons: end of public interface * * here be dragons: end of public interface *
****************************************************************************/ ****************************************************************************/
public: public:
/** @cond PRIVATE */ /// @cond PRIVATE
enum linking_operation { enum linking_operation {
establish_link_op, establish_link_op,
...@@ -274,7 +230,7 @@ class abstract_actor : public abstract_channel { ...@@ -274,7 +230,7 @@ class abstract_actor : public abstract_channel {
// Tries to run a custom exception handler for `eptr`. // Tries to run a custom exception handler for `eptr`.
optional<uint32_t> handle(const std::exception_ptr& eptr); optional<uint32_t> handle(const std::exception_ptr& eptr);
protected: protected:
virtual bool link_impl(linking_operation op, const actor_addr& other); virtual bool link_impl(linking_operation op, const actor_addr& other);
bool establish_link_impl(const actor_addr& other); bool establish_link_impl(const actor_addr& other);
...@@ -286,8 +242,8 @@ class abstract_actor : public abstract_channel { ...@@ -286,8 +242,8 @@ class abstract_actor : public abstract_channel {
bool remove_backlink_impl(const actor_addr& other); bool remove_backlink_impl(const actor_addr& other);
inline void attach_impl(attachable_ptr& ptr) { inline void attach_impl(attachable_ptr& ptr) {
ptr->next.swap(m_attachables_head); ptr->next.swap(attachables_head_);
m_attachables_head.swap(ptr); attachables_head_.swap(ptr);
} }
static size_t detach_impl(const attachable::token& what, static size_t detach_impl(const attachable::token& what,
...@@ -296,25 +252,25 @@ class abstract_actor : public abstract_channel { ...@@ -296,25 +252,25 @@ class abstract_actor : public abstract_channel {
bool dry_run = false); bool dry_run = false);
// cannot be changed after construction // cannot be changed after construction
const actor_id m_id; const actor_id id_;
// initially set to exit_reason::not_exited // initially set to exit_reason::not_exited
std::atomic<uint32_t> m_exit_reason; std::atomic<uint32_t> exit_reason_;
// guards access to m_exit_reason, m_attachables, m_links, // guards access to exit_reason_, attachables_, links_,
// and enqueue operations if actor is thread-mapped // and enqueue operations if actor is thread-mapped
mutable std::mutex m_mtx; mutable std::mutex mtx_;
// only used in blocking and thread-mapped actors // only used in blocking and thread-mapped actors
mutable std::condition_variable m_cv; mutable std::condition_variable cv_;
// attached functors that are executed on cleanup (monitors, links, etc) // attached functors that are executed on cleanup (monitors, links, etc)
attachable_ptr m_attachables_head; attachable_ptr attachables_head_;
// identifies the execution unit this actor is currently executed by // identifies the execution unit this actor is currently executed by
execution_unit* m_host; execution_unit* host_;
/** @endcond */ /// @endcond
}; };
} // namespace caf } // namespace caf
......
...@@ -29,43 +29,33 @@ ...@@ -29,43 +29,33 @@
namespace caf { namespace caf {
/** /// Interface for all message receivers. * This interface describes an
* Interface for all message receivers. * This interface describes an /// entity that can receive messages and is implemented by {@link actor}
* entity that can receive messages and is implemented by {@link actor} /// and {@link group}.
* and {@link group}.
*/
class abstract_channel : public ref_counted { class abstract_channel : public ref_counted {
public: public:
friend class abstract_actor; friend class abstract_actor;
friend class abstract_group; friend class abstract_group;
virtual ~abstract_channel(); virtual ~abstract_channel();
/** /// Enqueues a new message to the channel.
* Enqueues a new message to the channel.
*/
virtual void enqueue(const actor_addr& sender, message_id mid, virtual void enqueue(const actor_addr& sender, message_id mid,
message content, execution_unit* host) = 0; message content, execution_unit* host) = 0;
/** /// Enqueues a new message wrapped in a `mailbox_element` to the channel.
* Enqueues a new message wrapped in a `mailbox_element` to the channel. /// This variant is used by actors whenever it is possible to allocate
* This variant is used by actors whenever it is possible to allocate /// mailbox element and message on the same memory block and is thus
* mailbox element and message on the same memory block and is thus /// more efficient. Non-actors use the default implementation which simply
* more efficient. Non-actors use the default implementation which simply /// calls the pure virtual version.
* calls the pure virtual version.
*/
virtual void enqueue(mailbox_element_ptr what, execution_unit* host); virtual void enqueue(mailbox_element_ptr what, execution_unit* host);
/** /// Returns the ID of the node this actor is running on.
* Returns the ID of the node this actor is running on.
*/
inline node_id node() const { inline node_id node() const {
return m_node; return node_;
} }
/** /// Returns true if {@link node_ptr} returns
* Returns true if {@link node_ptr} returns
*/
bool is_remote() const; bool is_remote() const;
static constexpr int is_abstract_actor_flag = 0x100000; static constexpr int is_abstract_actor_flag = 0x100000;
...@@ -80,7 +70,7 @@ class abstract_channel : public ref_counted { ...@@ -80,7 +70,7 @@ class abstract_channel : public ref_counted {
return static_cast<bool>(flags() & is_abstract_group_flag); return static_cast<bool>(flags() & is_abstract_group_flag);
} }
protected: protected:
// note: *both* operations use relaxed memory order, this is because // note: *both* operations use relaxed memory order, this is because
// only the actor itself is granted write access while all access // only the actor itself is granted write access while all access
// from other actors or threads is always read-only; further, only // from other actors or threads is always read-only; further, only
...@@ -88,11 +78,11 @@ class abstract_channel : public ref_counted { ...@@ -88,11 +78,11 @@ class abstract_channel : public ref_counted {
// read by others, i.e., there is no acquire/release semantic between // read by others, i.e., there is no acquire/release semantic between
// setting and reading flags // setting and reading flags
inline int flags() const { inline int flags() const {
return m_flags.load(std::memory_order_relaxed); return flags_.load(std::memory_order_relaxed);
} }
inline void flags(int new_value) { inline void flags(int new_value) {
m_flags.store(new_value, std::memory_order_relaxed); flags_.store(new_value, std::memory_order_relaxed);
} }
private: private:
...@@ -105,15 +95,13 @@ private: ...@@ -105,15 +95,13 @@ private:
* first 20 bits, i.e., the bitmask 0xFFF00000 is reserved for * first 20 bits, i.e., the bitmask 0xFFF00000 is reserved for
* channel-related flags. * channel-related flags.
*/ */
std::atomic<int> m_flags; std::atomic<int> flags_;
// identifies the node of this channel // identifies the node of this channel
node_id m_node; node_id node_;
}; };
/** /// A smart pointer to an abstract channel.
* A smart pointer to an abstract channel. /// @relates abstract_channel_ptr
* @relates abstract_channel_ptr
*/
using abstract_channel_ptr = intrusive_ptr<abstract_channel>; using abstract_channel_ptr = intrusive_ptr<abstract_channel>;
} // namespace caf } // namespace caf
......
...@@ -46,7 +46,7 @@ class abstract_event_based_actor : public ...@@ -46,7 +46,7 @@ class abstract_event_based_actor : public
::with<mixin::sync_sender<nonblocking_response_handle_tag>::template impl>, ::with<mixin::sync_sender<nonblocking_response_handle_tag>::template impl>,
local_actor local_actor
>::type { >::type {
public: public:
using behavior_type = BehaviorType; using behavior_type = BehaviorType;
/**************************************************************************** /****************************************************************************
...@@ -63,7 +63,7 @@ class abstract_event_based_actor : public ...@@ -63,7 +63,7 @@ class abstract_event_based_actor : public
template <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< typename std::enable_if<
!std::is_same<keep_behavior_t, typename std::decay<T>::type>::value, ! std::is_same<keep_behavior_t, typename std::decay<T>::type>::value,
void void
>::type >::type
become(T&& x, Ts&&... xs) { become(T&& x, Ts&&... xs) {
...@@ -78,10 +78,10 @@ class abstract_event_based_actor : public ...@@ -78,10 +78,10 @@ class abstract_event_based_actor : public
} }
void unbecome() { void unbecome() {
this->m_bhvr_stack.pop_back(); this->bhvr_stack_.pop_back();
} }
private: private:
template <class... Ts> template <class... Ts>
static behavior& unbox(typed_behavior<Ts...>& x) { static behavior& unbox(typed_behavior<Ts...>& x) {
return x.unbox(); return x.unbox();
......
...@@ -44,11 +44,9 @@ class serializer; ...@@ -44,11 +44,9 @@ class serializer;
class local_actor; class local_actor;
class deserializer; class deserializer;
/** /// A multicast group.
* A multicast group.
*/
class abstract_group : public abstract_channel { class abstract_group : public abstract_channel {
public: public:
friend class detail::group_manager; friend class detail::group_manager;
friend class detail::peer_connection; friend class detail::peer_connection;
friend class local_actor; friend class local_actor;
...@@ -65,14 +63,14 @@ class abstract_group : public abstract_channel { ...@@ -65,14 +63,14 @@ class abstract_group : public abstract_channel {
class subscription_predicate { class subscription_predicate {
public: public:
inline subscription_predicate(intrusive_ptr<abstract_group> group) inline subscription_predicate(intrusive_ptr<abstract_group> group)
: m_group(std::move(group)) { : group_(std::move(group)) {
// nop // nop
} }
inline bool operator()(const attachable_ptr& ptr) { inline bool operator()(const attachable_ptr& ptr) {
return ptr->matches(subscription_token{m_group}); return ptr->matches(subscription_token{group_});
} }
private: private:
intrusive_ptr<abstract_group> m_group; intrusive_ptr<abstract_group> group_;
}; };
// needs access to unsubscribe() // needs access to unsubscribe()
...@@ -92,43 +90,35 @@ class abstract_group : public abstract_channel { ...@@ -92,43 +90,35 @@ class abstract_group : public abstract_channel {
} }
const intrusive_ptr<abstract_group>& group() const { const intrusive_ptr<abstract_group>& group() const {
return m_group; return group_;
} }
private: private:
intrusive_ptr<abstract_group> m_group; intrusive_ptr<abstract_group> group_;
}; };
/** /// Interface for user-defined multicast implementations.
* Interface for user-defined multicast implementations.
*/
class module { class module {
public: public:
module(std::string module_name); module(std::string module_name);
virtual ~module(); virtual ~module();
/** /// Stops all groups from this module.
* Stops all groups from this module.
*/
virtual void stop() = 0; virtual void stop() = 0;
/** /// Returns the name of this module implementation.
* Returns the name of this module implementation. /// @threadsafe
* @threadsafe
*/
const std::string& name(); const std::string& name();
/** /// Returns a pointer to the group associated with the name `group_name`.
* Returns a pointer to the group associated with the name `group_name`. /// @threadsafe
* @threadsafe
*/
virtual group get(const std::string& group_name) = 0; virtual group get(const std::string& group_name) = 0;
virtual group deserialize(deserializer* source) = 0; virtual group deserialize(deserializer* source) = 0;
private: private:
std::string m_name; std::string name_;
}; };
using module_ptr = module*; using module_ptr = module*;
...@@ -136,41 +126,31 @@ class abstract_group : public abstract_channel { ...@@ -136,41 +126,31 @@ class abstract_group : public abstract_channel {
virtual void serialize(serializer* sink) = 0; virtual void serialize(serializer* sink) = 0;
/** /// Returns a string representation of the group identifier, e.g.,
* Returns a string representation of the group identifier, e.g., /// "224.0.0.1" for IPv4 multicast or a user-defined string for local groups.
* "224.0.0.1" for IPv4 multicast or a user-defined string for local groups.
*/
const std::string& identifier() const; const std::string& identifier() const;
module_ptr get_module() const; module_ptr get_module() const;
/** /// Returns the name of the module.
* Returns the name of the module.
*/
const std::string& module_name() const; const std::string& module_name() const;
/** /// Subscribes `who` to this group and returns a subscription object.
* Subscribes `who` to this group and returns a subscription object.
*/
virtual attachable_ptr subscribe(const actor_addr& who) = 0; virtual attachable_ptr subscribe(const actor_addr& who) = 0;
/** /// Stops any background actors or threads and IO handles.
* Stops any background actors or threads and IO handles.
*/
virtual void stop() = 0; virtual void stop() = 0;
protected: protected:
abstract_group(module_ptr module, std::string group_id); abstract_group(module_ptr module, std::string group_id);
// called by subscription objects // called by subscription objects
virtual void unsubscribe(const actor_addr& who) = 0; virtual void unsubscribe(const actor_addr& who) = 0;
module_ptr m_module; module_ptr module_;
std::string m_identifier; std::string identifier_;
}; };
/** /// A smart pointer type that manages instances of {@link group}.
* A smart pointer type that manages instances of {@link group}. /// @relates group
* @relates group
*/
using abstract_group_ptr = intrusive_ptr<abstract_group>; using abstract_group_ptr = intrusive_ptr<abstract_group>;
} // namespace caf } // namespace caf
......
...@@ -41,10 +41,8 @@ struct invalid_actor_t { ...@@ -41,10 +41,8 @@ struct invalid_actor_t {
constexpr invalid_actor_t() {} constexpr invalid_actor_t() {}
}; };
/** /// Identifies an invalid {@link actor}.
* Identifies an invalid {@link actor}. /// @relates actor
* @relates actor
*/
constexpr invalid_actor_t invalid_actor = invalid_actor_t{}; constexpr invalid_actor_t invalid_actor = invalid_actor_t{};
template <class T> template <class T>
...@@ -55,10 +53,8 @@ struct is_convertible_to_actor { ...@@ -55,10 +53,8 @@ struct is_convertible_to_actor {
|| std::is_same<scoped_actor, type>::value; || std::is_same<scoped_actor, type>::value;
}; };
/** /// Identifies an untyped actor. Can be used with derived types
* Identifies an untyped actor. Can be used with derived types /// of `event_based_actor`, `blocking_actor`, and `actor_proxy`.
* of `event_based_actor`, `blocking_actor`, and `actor_proxy`.
*/
class actor : detail::comparable<actor>, class actor : detail::comparable<actor>,
detail::comparable<actor, actor_addr>, detail::comparable<actor, actor_addr>,
detail::comparable<actor, invalid_actor_t>, detail::comparable<actor, invalid_actor_t>,
...@@ -69,7 +65,7 @@ class actor : detail::comparable<actor>, ...@@ -69,7 +65,7 @@ class actor : detail::comparable<actor>,
template <class T, typename U> template <class T, typename U>
friend T actor_cast(const U&); friend T actor_cast(const U&);
public: public:
actor() = default; actor() = default;
...@@ -80,12 +76,12 @@ class actor : detail::comparable<actor>, ...@@ -80,12 +76,12 @@ class actor : detail::comparable<actor>,
template <class T> template <class T>
actor(intrusive_ptr<T> ptr, actor(intrusive_ptr<T> ptr,
typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0) typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0)
: m_ptr(std::move(ptr)) {} : ptr_(std::move(ptr)) {}
template <class T> template <class T>
actor(T* ptr, actor(T* ptr,
typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0) typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0)
: m_ptr(ptr) {} : ptr_(ptr) {}
actor(const invalid_actor_t&); actor(const invalid_actor_t&);
...@@ -112,22 +108,20 @@ class actor : detail::comparable<actor>, ...@@ -112,22 +108,20 @@ class actor : detail::comparable<actor>,
actor& operator=(const invalid_actor_t&); actor& operator=(const invalid_actor_t&);
inline operator bool() const { inline operator bool() const {
return static_cast<bool>(m_ptr); return static_cast<bool>(ptr_);
} }
inline bool operator!() const { inline bool operator!() const {
return !m_ptr; return ! ptr_;
} }
/** /// Returns a handle that grants access to actor operations such as enqueue.
* Returns a handle that grants access to actor operations such as enqueue.
*/
inline abstract_actor* operator->() const { inline abstract_actor* operator->() const {
return m_ptr.get(); return ptr_.get();
} }
inline abstract_actor& operator*() const { inline abstract_actor& operator*() const {
return *m_ptr; return *ptr_;
} }
intptr_t compare(const actor& other) const; intptr_t compare(const actor& other) const;
...@@ -135,36 +129,32 @@ class actor : detail::comparable<actor>, ...@@ -135,36 +129,32 @@ class actor : detail::comparable<actor>,
intptr_t compare(const actor_addr&) const; intptr_t compare(const actor_addr&) const;
inline intptr_t compare(const invalid_actor_t&) const { inline intptr_t compare(const invalid_actor_t&) const {
return m_ptr ? 1 : 0; return ptr_ ? 1 : 0;
} }
inline intptr_t compare(const invalid_actor_addr_t&) const { inline intptr_t compare(const invalid_actor_addr_t&) const {
return compare(invalid_actor); return compare(invalid_actor);
} }
/** /// Returns the address of the stored actor.
* Returns the address of the stored actor.
*/
actor_addr address() const; actor_addr address() const;
/** /// Returns whether this is an handle to a remote actor.
* Returns whether this is an handle to a remote actor.
*/
bool is_remote() const; bool is_remote() const;
actor_id id() const; actor_id id() const;
void swap(actor& other); void swap(actor& other);
private: private:
inline abstract_actor* get() const { inline abstract_actor* get() const {
return m_ptr.get(); return ptr_.get();
} }
actor(abstract_actor*); actor(abstract_actor*);
abstract_actor_ptr m_ptr; abstract_actor_ptr ptr_;
}; };
......
...@@ -39,15 +39,11 @@ struct invalid_actor_addr_t { ...@@ -39,15 +39,11 @@ struct invalid_actor_addr_t {
}; };
/** /// Identifies an invalid {@link actor_addr}.
* Identifies an invalid {@link actor_addr}. /// @relates actor_addr
* @relates actor_addr
*/
constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{}; constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{};
/** /// Stores the address of typed as well as untyped actors.
* Stores the address of typed as well as untyped actors.
*/
class actor_addr : detail::comparable<actor_addr>, class actor_addr : detail::comparable<actor_addr>,
detail::comparable<actor_addr, abstract_actor*>, detail::comparable<actor_addr, abstract_actor*>,
detail::comparable<actor_addr, abstract_actor_ptr> { detail::comparable<actor_addr, abstract_actor_ptr> {
...@@ -58,7 +54,7 @@ class actor_addr : detail::comparable<actor_addr>, ...@@ -58,7 +54,7 @@ class actor_addr : detail::comparable<actor_addr>,
template <class T, typename U> template <class T, typename U>
friend T actor_cast(const U&); friend T actor_cast(const U&);
public: public:
actor_addr() = default; actor_addr() = default;
...@@ -74,9 +70,9 @@ class actor_addr : detail::comparable<actor_addr>, ...@@ -74,9 +70,9 @@ class actor_addr : detail::comparable<actor_addr>,
actor_addr operator=(const invalid_actor_addr_t&); actor_addr operator=(const invalid_actor_addr_t&);
inline explicit operator bool() const { return static_cast<bool>(m_ptr); } inline explicit operator bool() const { return static_cast<bool>(ptr_); }
inline bool operator!() const { return !m_ptr; } inline bool operator!() const { return ! ptr_; }
intptr_t compare(const actor_addr& other) const; intptr_t compare(const actor_addr& other) const;
...@@ -90,24 +86,20 @@ class actor_addr : detail::comparable<actor_addr>, ...@@ -90,24 +86,20 @@ class actor_addr : detail::comparable<actor_addr>,
node_id node() const; node_id node() const;
/** /// Returns whether this is an address of a remote actor.
* Returns whether this is an address of a remote actor.
*/
bool is_remote() const; bool is_remote() const;
/** /// Returns the set of accepted messages types as strings or
* Returns the set of accepted messages types as strings or /// an empty set if this actor is untyped.
* an empty set if this actor is untyped.
*/
std::set<std::string> message_types() const; std::set<std::string> message_types() const;
private: private:
inline abstract_actor* get() const { return m_ptr.get(); } inline abstract_actor* get() const { return ptr_.get(); }
explicit actor_addr(abstract_actor*); explicit actor_addr(abstract_actor*);
abstract_actor_ptr m_ptr; abstract_actor_ptr ptr_;
}; };
......
...@@ -22,9 +22,7 @@ ...@@ -22,9 +22,7 @@
namespace caf { namespace caf {
/** /// Converts actor handle `what` to a different actor handle of type `T`.
* Converts actor handle `what` to a different actor handle of type `T`.
*/
template <class T, typename U> template <class T, typename U>
T actor_cast(const U& what) { T actor_cast(const U& what) {
return what.get(); return what.get();
......
...@@ -34,28 +34,22 @@ ...@@ -34,28 +34,22 @@
namespace caf { namespace caf {
/** /// An co-existing forwarding all messages through a user-defined
* An co-existing forwarding all messages through a user-defined /// callback to another object, thus serving as gateway to
* callback to another object, thus serving as gateway to /// allow any object to interact with other actors.
* allow any object to interact with other actors. /// @extends local_actor
* @extends local_actor
*/
class actor_companion : public abstract_event_based_actor<behavior, true> { class actor_companion : public abstract_event_based_actor<behavior, true> {
public: public:
using lock_type = detail::shared_spinlock; using lock_type = detail::shared_spinlock;
using message_pointer = std::unique_ptr<mailbox_element, detail::disposer>; using message_pointer = std::unique_ptr<mailbox_element, detail::disposer>;
using enqueue_handler = std::function<void (message_pointer)>; using enqueue_handler = std::function<void (message_pointer)>;
/** /// Removes the handler for incoming messages and terminates
* Removes the handler for incoming messages and terminates /// the companion for exit reason @ rsn.
* the companion for exit reason @ rsn.
*/
void disconnect(std::uint32_t rsn = exit_reason::normal); void disconnect(std::uint32_t rsn = exit_reason::normal);
/** /// Sets the handler for incoming messages.
* Sets the handler for incoming messages. /// @warning `handler` needs to be thread-safe
* @warning `handler` needs to be thread-safe
*/
void on_enqueue(enqueue_handler handler); void on_enqueue(enqueue_handler handler);
void enqueue(mailbox_element_ptr what, execution_unit* host) override; void enqueue(mailbox_element_ptr what, execution_unit* host) override;
...@@ -65,18 +59,16 @@ class actor_companion : public abstract_event_based_actor<behavior, true> { ...@@ -65,18 +59,16 @@ class actor_companion : public abstract_event_based_actor<behavior, true> {
void initialize(); void initialize();
private: private:
// set by parent to define custom enqueue action // set by parent to define custom enqueue action
enqueue_handler m_on_enqueue; enqueue_handler on_enqueue_;
// guards access to m_handler // guards access to handler_
lock_type m_lock; lock_type lock_;
}; };
/** /// A pointer to a co-existing (actor) object.
* A pointer to a co-existing (actor) object. /// @relates actor_companion
* @relates actor_companion
*/
using actor_companion_ptr = intrusive_ptr<actor_companion>; using actor_companion_ptr = intrusive_ptr<actor_companion>;
} // namespace caf } // namespace caf
......
...@@ -33,96 +33,66 @@ namespace caf { ...@@ -33,96 +33,66 @@ namespace caf {
class serializer; class serializer;
class deserializer; class deserializer;
/** /// Groups a (distributed) set of actors and allows actors
* Groups a (distributed) set of actors and allows actors /// in the same namespace to exchange messages.
* in the same namespace to exchange messages.
*/
class actor_namespace { class actor_namespace {
public: public:
using key_type = node_id; using key_type = node_id;
/** /// The backend of an actor namespace is responsible for creating proxy actors.
* The backend of an actor namespace is responsible for creating proxy actors.
*/
class backend { class backend {
public: public:
virtual ~backend(); virtual ~backend();
/** /// Creates a new proxy instance.
* Creates a new proxy instance.
*/
virtual actor_proxy_ptr make_proxy(const key_type&, actor_id) = 0; virtual actor_proxy_ptr make_proxy(const key_type&, actor_id) = 0;
}; };
actor_namespace(backend& mgm); actor_namespace(backend& mgm);
/** /// Writes an actor address to `sink` and adds the actor
* Writes an actor address to `sink` and adds the actor /// to the list of known actors for a later deserialization.
* to the list of known actors for a later deserialization.
*/
void write(serializer* sink, const actor_addr& ptr); void write(serializer* sink, const actor_addr& ptr);
/** /// Reads an actor address from `source,` creating
* Reads an actor address from `source,` creating /// addresses for remote actors on the fly if needed.
* addresses for remote actors on the fly if needed.
*/
actor_addr read(deserializer* source); actor_addr read(deserializer* source);
/** /// A map that stores all proxies for known remote actors.
* A map that stores all proxies for known remote actors.
*/
using proxy_map = std::map<actor_id, actor_proxy::anchor_ptr>; using proxy_map = std::map<actor_id, actor_proxy::anchor_ptr>;
/** /// Returns the number of proxies for `node`.
* Returns the number of proxies for `node`.
*/
size_t count_proxies(const key_type& node); size_t count_proxies(const key_type& node);
/** /// Returns all proxies for `node`.
* Returns all proxies for `node`.
*/
std::vector<actor_proxy_ptr> get_all(); std::vector<actor_proxy_ptr> get_all();
/** /// Returns all proxies for `node`.
* Returns all proxies for `node`.
*/
std::vector<actor_proxy_ptr> get_all(const key_type& node); std::vector<actor_proxy_ptr> get_all(const key_type& node);
/** /// Returns the proxy instance identified by `node` and `aid`
* Returns the proxy instance identified by `node` and `aid` /// or `nullptr` if the actor either unknown or expired.
* or `nullptr` if the actor either unknown or expired.
*/
actor_proxy_ptr get(const key_type& node, actor_id aid); actor_proxy_ptr get(const key_type& node, actor_id aid);
/** /// Returns the proxy instance identified by `node` and `aid`
* Returns the proxy instance identified by `node` and `aid` /// or creates a new (default) proxy instance.
* or creates a new (default) proxy instance.
*/
actor_proxy_ptr get_or_put(const key_type& node, actor_id aid); actor_proxy_ptr get_or_put(const key_type& node, actor_id aid);
/** /// Deletes all proxies for `node`.
* Deletes all proxies for `node`.
*/
void erase(const key_type& node); void erase(const key_type& node);
/** /// Deletes the proxy with id `aid` for `node`.
* Deletes the proxy with id `aid` for `node`.
*/
void erase(const key_type& node, actor_id aid); void erase(const key_type& node, actor_id aid);
/** /// Queries whether there are any proxies left.
* Queries whether there are any proxies left.
*/
bool empty() const; bool empty() const;
/** /// Deletes all proxies.
* Deletes all proxies.
*/
void clear(); void clear();
private: private:
backend& m_backend; backend& backend_;
std::map<key_type, proxy_map> m_proxies; std::map<key_type, proxy_map> proxies_;
}; };
} // namespace caf } // namespace caf
......
...@@ -31,7 +31,7 @@ class scoped_actor; ...@@ -31,7 +31,7 @@ class scoped_actor;
class actor_ostream { class actor_ostream {
public: public:
using fun_type = actor_ostream& (*)(actor_ostream&); using fun_type = actor_ostream& (*)(actor_ostream&);
...@@ -58,7 +58,7 @@ class actor_ostream { ...@@ -58,7 +58,7 @@ class actor_ostream {
template <class T> template <class T>
inline typename std::enable_if< inline typename std::enable_if<
!std::is_convertible<T, std::string>::value, actor_ostream& ! std::is_convertible<T, std::string>::value, actor_ostream&
>::type operator<<(T&& arg) { >::type operator<<(T&& arg) {
using std::to_string; using std::to_string;
return write(to_string(std::forward<T>(arg))); return write(to_string(std::forward<T>(arg)));
...@@ -68,10 +68,10 @@ class actor_ostream { ...@@ -68,10 +68,10 @@ class actor_ostream {
return f(*this); return f(*this);
} }
private: private:
actor m_self; actor self_;
actor m_printer; actor printer_;
}; };
......
...@@ -35,39 +35,35 @@ ...@@ -35,39 +35,35 @@
namespace caf { namespace caf {
/** /// An actor poool is a lightweight abstraction for a set of workers.
* An actor poool is a lightweight abstraction for a set of workers. /// The pool itself is an actor, meaning that it can be passed
* The pool itself is an actor, meaning that it can be passed /// around in an actor system to hide the actual set of workers.
* around in an actor system to hide the actual set of workers. ///
* /// After construction, new workers can be added via `{'SYS', 'PUT', actor}`
* After construction, new workers can be added via `{'SYS', 'PUT', actor}` /// messages, e.g., `send(my_pool, sys_atom::value, put_atom::value, worker)`.
* messages, e.g., `send(my_pool, sys_atom::value, put_atom::value, worker)`. /// `{'SYS', 'DELETE', actor}` messages remove a worker from the set,
* `{'SYS', 'DELETE', actor}` messages remove a worker from the set, /// whereas `{'SYS', 'GET'}` returns a `vector<actor>` containing all workers.
* whereas `{'SYS', 'GET'}` returns a `vector<actor>` containing all workers. ///
* /// Note that the pool *always* sends exit messages to all of its workers
* Note that the pool *always* sends exit messages to all of its workers /// when forced to quit. The pool monitors all of its workers. Messages queued
* when forced to quit. The pool monitors all of its workers. Messages queued /// up in a worker's mailbox are lost, i.e., the pool itself does not buffer
* up in a worker's mailbox are lost, i.e., the pool itself does not buffer /// and resend messages. Advanced caching or resend strategies can be
* and resend messages. Advanced caching or resend strategies can be /// implemented in a policy.
* implemented in a policy. ///
* /// It is wort mentioning that the pool is *not* an event-based actor.
* It is wort mentioning that the pool is *not* an event-based actor. /// Neither does it live in its own thread. Messages are dispatched immediately
* Neither does it live in its own thread. Messages are dispatched immediately /// during the enqueue operation. Any user-defined policy thus has to dispatch
* during the enqueue operation. Any user-defined policy thus has to dispatch /// messages with as little overhead as possible, because the dispatching
* messages with as little overhead as possible, because the dispatching /// runs in the context of the sender.
* runs in the context of the sender.
*/
class actor_pool : public abstract_actor { class actor_pool : public abstract_actor {
public: public:
using uplock = upgrade_lock<detail::shared_spinlock>; using uplock = upgrade_lock<detail::shared_spinlock>;
using actor_vec = std::vector<actor>; using actor_vec = std::vector<actor>;
using factory = std::function<actor ()>; using factory = std::function<actor ()>;
using policy = std::function<void (uplock&, const actor_vec&, using policy = std::function<void (uplock&, const actor_vec&,
mailbox_element_ptr&, execution_unit*)>; mailbox_element_ptr&, execution_unit*)>;
/** /// Default policy class implementing simple round robin dispatching.
* Default policy class implementing simple round robin dispatching.
*/
class round_robin { class round_robin {
public: public:
round_robin(); round_robin();
...@@ -76,21 +72,17 @@ class actor_pool : public abstract_actor { ...@@ -76,21 +72,17 @@ class actor_pool : public abstract_actor {
mailbox_element_ptr&, execution_unit*); mailbox_element_ptr&, execution_unit*);
private: private:
std::atomic<size_t> m_pos; std::atomic<size_t> pos_;
}; };
/** /// Default policy class implementing broadcast dispatching.
* Default policy class implementing broadcast dispatching.
*/
class broadcast { class broadcast {
public: public:
void operator()(uplock&, const actor_vec&, void operator()(uplock&, const actor_vec&,
mailbox_element_ptr&, execution_unit*); mailbox_element_ptr&, execution_unit*);
}; };
/** /// Default policy class implementing random dispatching.
* Default policy class implementing random dispatching.
*/
class random { class random {
public: public:
random(); random();
...@@ -99,18 +91,16 @@ class actor_pool : public abstract_actor { ...@@ -99,18 +91,16 @@ class actor_pool : public abstract_actor {
mailbox_element_ptr&, execution_unit*); mailbox_element_ptr&, execution_unit*);
private: private:
std::random_device m_rd; std::random_device rd_;
}; };
/** /// Default policy class implementing broadcast dispatching (split step)
* Default policy class implementing broadcast dispatching (split step) /// followed by a join operation `F` combining all individual results to
* followed by a join operation `F` combining all individual results to /// a single result of type `T`.
* a single result of type `T`. /// @tparam T Result type received by the original sender.
* @tparam T Result type received by the original sender. /// @tparam Join Functor with signature `void (T&, message&)`.
* @tparam Join Functor with signature `void (T&, message&)`. /// @tparam Split Functor with signature
* @tparam Split Functor with signature /// `void (vector<pair<actor, message>>&, message&)`.
* `void (vector<pair<actor, message>>&, message&)`.
*/
template <class T, class Join, class Split = detail::nop_split> template <class T, class Join, class Split = detail::nop_split>
static policy split_join(Join jf, Split sf = Split(), T init = T()) { static policy split_join(Join jf, Split sf = Split(), T init = T()) {
using impl = detail::split_join<T, Split, Join>; using impl = detail::split_join<T, Split, Join>;
...@@ -119,15 +109,11 @@ class actor_pool : public abstract_actor { ...@@ -119,15 +109,11 @@ class actor_pool : public abstract_actor {
~actor_pool(); ~actor_pool();
/** /// Returns an actor pool without workers using the dispatch policy `pol`.
* Returns an actor pool without workers using the dispatch policy `pol`.
*/
static actor make(policy pol); static actor make(policy pol);
/** /// Returns an actor pool with `n` workers created by the factory
* Returns an actor pool with `n` workers created by the factory /// function `fac` using the dispatch policy `pol`.
* function `fac` using the dispatch policy `pol`.
*/
static actor make(size_t n, factory fac, policy pol); static actor make(size_t n, factory fac, policy pol);
void enqueue(const actor_addr& sender, message_id mid, void enqueue(const actor_addr& sender, message_id mid,
...@@ -137,17 +123,17 @@ class actor_pool : public abstract_actor { ...@@ -137,17 +123,17 @@ class actor_pool : public abstract_actor {
actor_pool(); actor_pool();
private: private:
bool filter(upgrade_lock<detail::shared_spinlock>&, const actor_addr& sender, bool filter(upgrade_lock<detail::shared_spinlock>&, const actor_addr& sender,
message_id mid, const message& content, execution_unit* host); message_id mid, const message& content, execution_unit* host);
// call without m_mtx held // call without mtx_ held
void quit(); void quit();
detail::shared_spinlock m_mtx; detail::shared_spinlock mtx_;
std::vector<actor> m_workers; std::vector<actor> workers_;
policy m_policy; policy policy_;
uint32_t m_planned_reason; uint32_t planned_reason_;
}; };
} // namespace caf } // namespace caf
......
...@@ -31,22 +31,16 @@ namespace caf { ...@@ -31,22 +31,16 @@ namespace caf {
class actor_proxy; class actor_proxy;
/** /// A smart pointer to an {@link actor_proxy} instance.
* A smart pointer to an {@link actor_proxy} instance. /// @relates actor_proxy
* @relates actor_proxy
*/
using actor_proxy_ptr = intrusive_ptr<actor_proxy>; using actor_proxy_ptr = intrusive_ptr<actor_proxy>;
/** /// Represents an actor running on a remote machine,
* Represents an actor running on a remote machine, /// or different hardware, or in a separate process.
* or different hardware, or in a separate process.
*/
class actor_proxy : public abstract_actor { class actor_proxy : public abstract_actor {
public: public:
/** /// An anchor points to a proxy instance without sharing
* An anchor points to a proxy instance without sharing /// ownership to it, i.e., models a weak ptr.
* ownership to it, i.e., models a weak ptr.
*/
class anchor : public ref_counted { class anchor : public ref_counted {
public: public:
friend class actor_proxy; friend class actor_proxy;
...@@ -55,15 +49,11 @@ class actor_proxy : public abstract_actor { ...@@ -55,15 +49,11 @@ class actor_proxy : public abstract_actor {
~anchor(); ~anchor();
/** /// Queries whether the proxy was already deleted.
* Queries whether the proxy was already deleted.
*/
bool expired() const; bool expired() const;
/** /// Gets a pointer to the proxy or `nullptr`
* Gets a pointer to the proxy or `nullptr` /// if the instance is {@link expired()}.
* if the instance is {@link expired()}.
*/
actor_proxy_ptr get(); actor_proxy_ptr get();
private: private:
...@@ -72,39 +62,33 @@ class actor_proxy : public abstract_actor { ...@@ -72,39 +62,33 @@ class actor_proxy : public abstract_actor {
* count of the proxy is nonzero. * count of the proxy is nonzero.
*/ */
bool try_expire() noexcept; bool try_expire() noexcept;
std::atomic<actor_proxy*> m_ptr; std::atomic<actor_proxy*> ptr_;
detail::shared_spinlock m_lock; detail::shared_spinlock lock_;
}; };
using anchor_ptr = intrusive_ptr<anchor>; using anchor_ptr = intrusive_ptr<anchor>;
~actor_proxy(); ~actor_proxy();
/** /// Establishes a local link state that's not synchronized back
* Establishes a local link state that's not synchronized back /// to the remote instance.
* to the remote instance.
*/
virtual void local_link_to(const actor_addr& other) = 0; virtual void local_link_to(const actor_addr& other) = 0;
/** /// Removes a local link state.
* Removes a local link state.
*/
virtual void local_unlink_from(const actor_addr& other) = 0; virtual void local_unlink_from(const actor_addr& other) = 0;
/** /// Invokes cleanup code.
* Invokes cleanup code.
*/
virtual void kill_proxy(uint32_t reason) = 0; virtual void kill_proxy(uint32_t reason) = 0;
void request_deletion(bool decremented_ref_count) noexcept override; void request_deletion(bool decremented_ref_count) noexcept override;
inline anchor_ptr get_anchor() { inline anchor_ptr get_anchor() {
return m_anchor; return anchor_;
} }
protected: protected:
actor_proxy(actor_id aid, node_id nid); actor_proxy(actor_id aid, node_id nid);
anchor_ptr m_anchor; anchor_ptr anchor_;
}; };
} // namespace caf } // namespace caf
......
This diff is collapsed.
...@@ -36,63 +36,47 @@ ...@@ -36,63 +36,47 @@
namespace caf { namespace caf {
/** /// @addtogroup TypeSystem
* @addtogroup TypeSystem /// @{
* @{
*/ /// A simple example for announce with public accessible members.
/// The output of this example program is:
/** /// > foo(1, 2)<br>
* A simple example for announce with public accessible members. /// > foo_pair(3, 4)
* The output of this example program is: /// @example announce_1.cpp
* > foo(1, 2)<br>
* > foo_pair(3, 4) /// An example for announce with getter and setter member functions.
* @example announce_1.cpp /// The output of this example program is:
*/ ///
/// > foo(1, 2)
/** /// @example announce_2.cpp
* An example for announce with getter and setter member functions.
* The output of this example program is: /// An example for announce with overloaded getter and setter member functions.
* /// The output of this example program is:
* > foo(1, 2) ///
* @example announce_2.cpp /// > foo(1, 2)
*/ /// @example announce_3.cpp
/** /// An example for announce with non-primitive members.
* An example for announce with overloaded getter and setter member functions. /// The output of this example program is:
* The output of this example program is: ///
* /// > bar(foo(1, 2), 3)
* > foo(1, 2) /// @example announce_4.cpp
* @example announce_3.cpp
*/ /// An advanced example for announce implementing serialization
/// for a user-defined tree data type.
/** /// @example announce_5.cpp
* An example for announce with non-primitive members.
* The output of this example program is: /// Adds a new mapping to the type system. Returns `utype.get()` on
* /// success, otherwise a pointer to the previously installed singleton.
* > bar(foo(1, 2), 3) /// @warning `announce` is **not** thead-safe!
* @example announce_4.cpp
*/
/**
* An advanced example for announce implementing serialization
* for a user-defined tree data type.
* @example announce_5.cpp
*/
/**
* Adds a new mapping to the type system. Returns `utype.get()` on
* success, otherwise a pointer to the previously installed singleton.
* @warning `announce` is **not** thead-safe!
*/
const uniform_type_info* announce(const std::type_info& tinfo, const uniform_type_info* announce(const std::type_info& tinfo,
uniform_type_info_ptr utype); uniform_type_info_ptr utype);
// deals with member pointer // deals with member pointer
/** /// Creates meta information for a non-trivial `Member`,
* Creates meta information for a non-trivial `Member`, /// whereas `xs` are the "sub-members" of `Member`.
* whereas `xs` are the "sub-members" of `Member`. /// @see {@link announce_4.cpp announce example 4}
* @see {@link announce_4.cpp announce example 4}
*/
template <class Member, class Parent, class... Ts> template <class Member, class Parent, class... Ts>
std::pair<Member Parent::*, detail::abstract_uniform_type_info<Member>*> std::pair<Member Parent::*, detail::abstract_uniform_type_info<Member>*>
compound_member(Member Parent::*memptr, const Ts&... xs) { compound_member(Member Parent::*memptr, const Ts&... xs) {
...@@ -100,12 +84,10 @@ compound_member(Member Parent::*memptr, const Ts&... xs) { ...@@ -100,12 +84,10 @@ compound_member(Member Parent::*memptr, const Ts&... xs) {
} }
// deals with getter returning a mutable reference // deals with getter returning a mutable reference
/** /// Creates meta information for a non-trivial `Member` accessed
* Creates meta information for a non-trivial `Member` accessed /// via the getter member function `getter` returning a mutable reference,
* via the getter member function `getter` returning a mutable reference, /// whereas `xs` are the "sub-members" of `Member`.
* whereas `xs` are the "sub-members" of `Member`. /// @see {@link announce_4.cpp announce example 4}
* @see {@link announce_4.cpp announce example 4}
*/
template <class Member, class Parent, class... Ts> template <class Member, class Parent, class... Ts>
std::pair<Member& (Parent::*)(), detail::abstract_uniform_type_info<Member>*> std::pair<Member& (Parent::*)(), detail::abstract_uniform_type_info<Member>*>
compound_member(Member& (Parent::*getter)(), const Ts&... xs) { compound_member(Member& (Parent::*getter)(), const Ts&... xs) {
...@@ -113,12 +95,10 @@ compound_member(Member& (Parent::*getter)(), const Ts&... xs) { ...@@ -113,12 +95,10 @@ compound_member(Member& (Parent::*getter)(), const Ts&... xs) {
} }
// deals with getter/setter pair // deals with getter/setter pair
/** /// Creates meta information for a non-trivial `Member` accessed
* Creates meta information for a non-trivial `Member` accessed /// via the pair of getter and setter member function pointers `gspair`,
* via the pair of getter and setter member function pointers `gspair`, /// whereas `xs` are the "sub-members" of `Member`.
* whereas `xs` are the "sub-members" of `Member`. /// @see {@link announce_4.cpp announce example 4}
* @see {@link announce_4.cpp announce example 4}
*/
template <class Parent, class GRes, class SRes, class SArg, class... Ts> template <class Parent, class GRes, class SRes, class SArg, class... Ts>
std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>, std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>,
detail::abstract_uniform_type_info<typename std::decay<GRes>::type>*> detail::abstract_uniform_type_info<typename std::decay<GRes>::type>*>
...@@ -129,11 +109,9 @@ compound_member(const std::pair<GRes (Parent::*)() const, ...@@ -129,11 +109,9 @@ compound_member(const std::pair<GRes (Parent::*)() const,
return {gspair, new detail::default_uniform_type_info<mtype>("???", xs...)}; return {gspair, new detail::default_uniform_type_info<mtype>("???", xs...)};
} }
/** /// Adds a new type mapping for `T` to the type system using `tname`
* Adds a new type mapping for `T` to the type system using `tname` /// as its uniform name and the list of member pointers `xs`.
* as its uniform name and the list of member pointers `xs`. /// @warning `announce` is **not** thead-safe!
* @warning `announce` is **not** thead-safe!
*/
template <class T, class... Ts> template <class T, class... Ts>
inline const uniform_type_info* announce(std::string tname, const Ts&... xs) { inline const uniform_type_info* announce(std::string tname, const Ts&... xs) {
static_assert(std::is_pod<T>::value || std::is_empty<T>::value static_assert(std::is_pod<T>::value || std::is_empty<T>::value
...@@ -143,9 +121,7 @@ inline const uniform_type_info* announce(std::string tname, const Ts&... xs) { ...@@ -143,9 +121,7 @@ inline const uniform_type_info* announce(std::string tname, const Ts&... xs) {
return announce(typeid(T), uniform_type_info_ptr{ptr}); return announce(typeid(T), uniform_type_info_ptr{ptr});
} }
/** /// @}
* @}
*/
} // namespace caf } // namespace caf
......
...@@ -24,32 +24,24 @@ ...@@ -24,32 +24,24 @@
namespace caf { namespace caf {
/** /// Acts as wildcard expression in patterns.
* Acts as wildcard expression in patterns.
*/
struct anything { struct anything {
constexpr anything() { constexpr anything() {
// nop // nop
} }
}; };
/** /// @relates anything
* @relates anything
*/
inline bool operator==(const anything&, const anything&) { inline bool operator==(const anything&, const anything&) {
return true; return true;
} }
/** /// @relates anything
* @relates anything
*/
inline bool operator!=(const anything&, const anything&) { inline bool operator!=(const anything&, const anything&) {
return false; return false;
} }
/** /// @relates anything
* @relates anything
*/
template <class T> template <class T>
struct is_anything : std::is_same<T, anything> { struct is_anything : std::is_same<T, anything> {
// no content // no content
......
...@@ -27,18 +27,14 @@ ...@@ -27,18 +27,14 @@
namespace caf { namespace caf {
/** /// The value type of atoms.
* The value type of atoms.
*/
enum class atom_value : uint64_t { enum class atom_value : uint64_t {
/** @cond PRIVATE */ /// @cond PRIVATE
dirty_little_hack = 31337 dirty_little_hack = 31337
/** @endcond */ /// @endcond
}; };
/** /// Creates an atom from given string literal.
* Creates an atom from given string literal.
*/
template <size_t Size> template <size_t Size>
constexpr atom_value atom(char const (&str)[Size]) { constexpr atom_value atom(char const (&str)[Size]) {
// last character is the NULL terminator // last character is the NULL terminator
...@@ -46,95 +42,63 @@ constexpr atom_value atom(char const (&str)[Size]) { ...@@ -46,95 +42,63 @@ constexpr atom_value atom(char const (&str)[Size]) {
return static_cast<atom_value>(detail::atom_val(str, 0xF)); return static_cast<atom_value>(detail::atom_val(str, 0xF));
} }
/** /// Lifts an `atom_value` to a compile-time constant.
* Lifts an `atom_value` to a compile-time constant.
*/
template <atom_value V> template <atom_value V>
struct atom_constant { struct atom_constant {
constexpr atom_constant() { constexpr atom_constant() {
// nop // nop
} }
/** /// Returns the wrapped value.
* Returns the wrapped value.
*/
constexpr operator atom_value() const { constexpr operator atom_value() const {
return V; return V;
} }
/** /// Returns an instance *of this constant* (*not* an `atom_value`).
* Returns an instance *of this constant* (*not* an `atom_value`).
*/
static const atom_constant value; static const atom_constant value;
}; };
template <atom_value V> template <atom_value V>
const atom_constant<V> atom_constant<V>::value = atom_constant<V>{}; const atom_constant<V> atom_constant<V>::value = atom_constant<V>{};
/** /// Generic 'ADD' atom for request operations.
* Generic 'ADD' atom for request operations.
*/
using add_atom = atom_constant<atom("ADD")>; using add_atom = atom_constant<atom("ADD")>;
/** /// Generic 'GET' atom for request operations.
* Generic 'GET' atom for request operations.
*/
using get_atom = atom_constant<atom("GET")>; using get_atom = atom_constant<atom("GET")>;
/** /// Generic 'PUT' atom for request operations.
* Generic 'PUT' atom for request operations.
*/
using put_atom = atom_constant<atom("PUT")>; using put_atom = atom_constant<atom("PUT")>;
/** /// Generic 'DELETE' atom for request operations.
* Generic 'DELETE' atom for request operations.
*/
using delete_atom = atom_constant<atom("DELETE")>; using delete_atom = atom_constant<atom("DELETE")>;
/** /// Generic 'OK' atom for response messages.
* Generic 'OK' atom for response messages.
*/
using ok_atom = atom_constant<atom("OK")>; using ok_atom = atom_constant<atom("OK")>;
/** /// Generic 'ERROR' atom for response messages.
* Generic 'ERROR' atom for response messages.
*/
using error_atom = atom_constant<atom("ERROR")>; using error_atom = atom_constant<atom("ERROR")>;
/** /// Marker 'SYS' atom for prefixing messages to a forwarding chain
* Marker 'SYS' atom for prefixing messages to a forwarding chain /// to address an otherwise transparent actor.
* to address an otherwise transparent actor.
*/
using sys_atom = atom_constant<atom("SYS")>; using sys_atom = atom_constant<atom("SYS")>;
/** /// Generic 'JOIN' atom, e.g., for signaling group subscriptions.
* Generic 'JOIN' atom, e.g., for signaling group subscriptions.
*/
using join_atom = atom_constant<atom("JOIN")>; using join_atom = atom_constant<atom("JOIN")>;
/** /// Generic 'LEAVE' atom, e.g., for signaling group unsubscriptions.
* Generic 'LEAVE' atom, e.g., for signaling group unsubscriptions.
*/
using leave_atom = atom_constant<atom("LEAVE")>; using leave_atom = atom_constant<atom("LEAVE")>;
/** /// Generic 'FORWARD' atom, e.g., for signaling an actor that it
* Generic 'FORWARD' atom, e.g., for signaling an actor that it /// should drop the first element and forward the remainder to
* should drop the first element and forward the remainder to /// a list of predefined receivers.
* a list of predefined receivers.
*/
using forward_atom = atom_constant<atom("FORWARD")>; using forward_atom = atom_constant<atom("FORWARD")>;
/** /// Generic 'FLUSH' atom, e.g., used by `aout`.
* Generic 'FLUSH' atom, e.g., used by `aout`.
*/
using flush_atom = atom_constant<atom("FLUSH")>; using flush_atom = atom_constant<atom("FLUSH")>;
/** /// Generic 'LINK' atom for link requests over network.
* Generic 'LINK' atom for link requests over network.
*/
using link_atom = atom_constant<atom("LINK")>; using link_atom = atom_constant<atom("LINK")>;
/** /// Generic 'UNLINK' atom for removing networked links.
* Generic 'UNLINK' atom for removing networked links.
*/
using unlink_atom = atom_constant<atom("UNLINK")>; using unlink_atom = atom_constant<atom("UNLINK")>;
} // namespace caf } // namespace caf
......
...@@ -31,32 +31,22 @@ namespace caf { ...@@ -31,32 +31,22 @@ namespace caf {
class abstract_actor; class abstract_actor;
/** /// Callback utility class.
* Callback utility class.
*/
class attachable { class attachable {
public: public:
attachable() = default; attachable() = default;
attachable(const attachable&) = delete; attachable(const attachable&) = delete;
attachable& operator=(const attachable&) = delete; attachable& operator=(const attachable&) = delete;
/** /// Represents a pointer to a value with its subtype as type ID number.
* Represents a pointer to a value with its subtype as type ID number.
*/
struct token { struct token {
/** /// Identifies a non-matchable subtype.
* Identifies a non-matchable subtype.
*/
static constexpr size_t anonymous = 0; static constexpr size_t anonymous = 0;
/** /// Identifies `abstract_group::subscription`.
* Identifies `abstract_group::subscription`.
*/
static constexpr size_t subscription = 1; static constexpr size_t subscription = 1;
/** /// Identifies `default_attachable::observe_token`.
* Identifies `default_attachable::observe_token`.
*/
static constexpr size_t observer = 2; static constexpr size_t observer = 2;
template <class T> template <class T>
...@@ -64,14 +54,10 @@ class attachable { ...@@ -64,14 +54,10 @@ class attachable {
// nop // nop
} }
/** /// Denotes the type of ptr.
* Denotes the type of ptr.
*/
size_t subtype; size_t subtype;
/** /// Any value, used to identify attachable instances.
* Any value, used to identify attachable instances.
*/
const void* ptr; const void* ptr;
token(size_t subtype, const void* ptr); token(size_t subtype, const void* ptr);
...@@ -79,29 +65,21 @@ class attachable { ...@@ -79,29 +65,21 @@ class attachable {
virtual ~attachable(); virtual ~attachable();
/** /// Executed if the actor did not handle an exception and must
* Executed if the actor did not handle an exception and must /// not return `none` if this attachable did handle `eptr`.
* not return `none` if this attachable did handle `eptr`. /// Note that the first handler to handle `eptr` "wins" and no other
* Note that the first handler to handle `eptr` "wins" and no other /// handler will be invoked.
* handler will be invoked. /// @returns The exit reason the actor should use.
* @returns The exit reason the actor should use.
*/
virtual optional<uint32_t> handle_exception(const std::exception_ptr& eptr); virtual optional<uint32_t> handle_exception(const std::exception_ptr& eptr);
/** /// Executed if the actor finished execution with given `reason`.
* Executed if the actor finished execution with given `reason`. /// The default implementation does nothing.
* The default implementation does nothing.
*/
virtual void actor_exited(abstract_actor* self, uint32_t reason); virtual void actor_exited(abstract_actor* self, uint32_t reason);
/** /// Returns `true` if `what` selects this instance, otherwise `false`.
* Returns `true` if `what` selects this instance, otherwise `false`.
*/
virtual bool matches(const token& what); virtual bool matches(const token& what);
/** /// Returns `true` if `what` selects this instance, otherwise `false`.
* Returns `true` if `what` selects this instance, otherwise `false`.
*/
template <class T> template <class T>
bool matches(const T& what) { bool matches(const T& what) {
return matches(token{T::token_type, &what}); return matches(token{T::token_type, &what});
...@@ -110,9 +88,7 @@ class attachable { ...@@ -110,9 +88,7 @@ class attachable {
std::unique_ptr<attachable> next; std::unique_ptr<attachable> next;
}; };
/** /// @relates attachable
* @relates attachable
*/
using attachable_ptr = std::unique_ptr<attachable>; using attachable_ptr = std::unique_ptr<attachable>;
} // namespace caf } // namespace caf
......
...@@ -25,11 +25,9 @@ ...@@ -25,11 +25,9 @@
namespace caf { namespace caf {
/** /// Blocks execution of this actor until all other actors finished execution.
* Blocks execution of this actor until all other actors finished execution. /// @warning This function will cause a deadlock if called from multiple actors.
* @warning This function will cause a deadlock if called from multiple actors. /// @warning Do not call this function in cooperatively scheduled actors.
* @warning Do not call this function in cooperatively scheduled actors.
*/
inline void await_all_actors_done() { inline void await_all_actors_done() {
detail::singletons::get_actor_registry()->await_running_count_equal(0); detail::singletons::get_actor_registry()->await_running_count_equal(0);
} }
......
...@@ -36,12 +36,10 @@ namespace caf { ...@@ -36,12 +36,10 @@ namespace caf {
class message_handler; class message_handler;
/** /// Describes the behavior of an actor, i.e., provides a message
* Describes the behavior of an actor, i.e., provides a message /// handler and an optional timeout.
* handler and an optional timeout.
*/
class behavior { class behavior {
public: public:
friend class message_handler; friend class message_handler;
behavior() = default; behavior() = default;
...@@ -50,96 +48,76 @@ class behavior { ...@@ -50,96 +48,76 @@ class behavior {
behavior& operator=(behavior&&) = default; behavior& operator=(behavior&&) = default;
behavior& operator=(const behavior&) = default; behavior& operator=(const behavior&) = default;
/** /// Creates a behavior from `fun` without timeout.
* Creates a behavior from `fun` without timeout.
*/
behavior(const message_handler& fun); behavior(const message_handler& fun);
/** /// The list of arguments can contain match expressions, message handlers,
* The list of arguments can contain match expressions, message handlers, /// and up to one timeout (if set, the timeout has to be the last argument).
* and up to one timeout (if set, the timeout has to be the last argument).
*/
template <class T, class... Ts> template <class T, class... Ts>
behavior(T x, Ts... xs) { behavior(T x, Ts... xs) {
assign(std::move(x), std::move(xs)...); assign(std::move(x), std::move(xs)...);
} }
/** /// Creates a behavior from `tdef` without message handler.
* Creates a behavior from `tdef` without message handler.
*/
template <class F> template <class F>
behavior(timeout_definition<F> tdef) : m_impl(detail::make_behavior(tdef)) { behavior(timeout_definition<F> tdef) : impl_(detail::make_behavior(tdef)) {
// nop // nop
} }
/** /// Assigns new handlers.
* Assigns new handlers.
*/
template <class... Ts> template <class... Ts>
void assign(Ts... xs) { void assign(Ts... xs) {
static_assert(sizeof...(Ts) > 0, "assign() called without arguments"); static_assert(sizeof...(Ts) > 0, "assign() called without arguments");
m_impl = detail::make_behavior(xs...); impl_ = detail::make_behavior(xs...);
} }
void assign(intrusive_ptr<detail::behavior_impl> ptr) { void assign(intrusive_ptr<detail::behavior_impl> ptr) {
m_impl.swap(ptr); impl_.swap(ptr);
} }
/** /// Equal to `*this = other`.
* Equal to `*this = other`.
*/
void assign(message_handler other); void assign(message_handler other);
/** /// Equal to `*this = other`.
* Equal to `*this = other`.
*/
void assign(behavior other); void assign(behavior other);
/** /// Invokes the timeout callback if set.
* Invokes the timeout callback if set.
*/
inline void handle_timeout() { inline void handle_timeout() {
m_impl->handle_timeout(); impl_->handle_timeout();
} }
/** /// Returns the duration after which receive operations
* Returns the duration after which receive operations /// using this behavior should time out.
* using this behavior should time out.
*/
inline const duration& timeout() const { inline const duration& timeout() const {
return m_impl->timeout(); return impl_->timeout();
} }
/** /// Runs this handler and returns its (optional) result.
* Runs this handler and returns its (optional) result.
*/
inline optional<message> operator()(message& arg) { inline optional<message> operator()(message& arg) {
return (m_impl) ? m_impl->invoke(arg) : none; return (impl_) ? impl_->invoke(arg) : none;
} }
/** /// Checks whether this behavior is not empty.
* Checks whether this behavior is not empty.
*/
inline operator bool() const { inline operator bool() const {
return static_cast<bool>(m_impl); return static_cast<bool>(impl_);
} }
/** @cond PRIVATE */ /// @cond PRIVATE
using impl_ptr = intrusive_ptr<detail::behavior_impl>; using impl_ptr = intrusive_ptr<detail::behavior_impl>;
inline const impl_ptr& as_behavior_impl() const { inline const impl_ptr& as_behavior_impl() const {
return m_impl; return impl_;
} }
inline behavior(impl_ptr ptr) : m_impl(std::move(ptr)) { inline behavior(impl_ptr ptr) : impl_(std::move(ptr)) {
// nop // nop
} }
/** @endcond */ /// @endcond
private: private:
impl_ptr m_impl; impl_ptr impl_;
}; };
} // namespace caf } // namespace caf
......
...@@ -28,11 +28,9 @@ struct keep_behavior_t { ...@@ -28,11 +28,9 @@ struct keep_behavior_t {
} }
}; };
/** /// Policy tag that causes {@link event_based_actor::become} to
* Policy tag that causes {@link event_based_actor::become} to /// keep the current behavior available.
* keep the current behavior available. /// @relates local_actor
* @relates local_actor
*/
constexpr keep_behavior_t keep_behavior = keep_behavior_t{}; constexpr keep_behavior_t keep_behavior = keep_behavior_t{};
} // namespace caf } // namespace caf
......
...@@ -24,19 +24,17 @@ ...@@ -24,19 +24,17 @@
namespace caf { namespace caf {
/** /// Implements the deserializer interface with a binary serialization protocol.
* Implements the deserializer interface with a binary serialization protocol.
*/
class binary_deserializer : public deserializer { class binary_deserializer : public deserializer {
using super = deserializer; using super = deserializer;
public: public:
binary_deserializer(const void* buf, size_t buf_size, binary_deserializer(const void* buf, size_t buf_size,
actor_namespace* ns = nullptr); actor_namespace* ns = nullptr);
binary_deserializer(const void* begin, const void* m_end, binary_deserializer(const void* begin, const void* end_,
actor_namespace* ns = nullptr); actor_namespace* ns = nullptr);
const uniform_type_info* begin_object() override; const uniform_type_info* begin_object() override;
...@@ -46,20 +44,16 @@ class binary_deserializer : public deserializer { ...@@ -46,20 +44,16 @@ class binary_deserializer : public deserializer {
void read_value(primitive_variant& storage) override; void read_value(primitive_variant& storage) override;
void read_raw(size_t num_bytes, void* storage) override; void read_raw(size_t num_bytes, void* storage) override;
/** /// Replaces the current read buffer.
* Replaces the current read buffer.
*/
void set_rdbuf(const void* buf, size_t buf_size); void set_rdbuf(const void* buf, size_t buf_size);
/** /// Replaces the current read buffer.
* Replaces the current read buffer. void set_rdbuf(const void* begin, const void* end_);
*/
void set_rdbuf(const void* begin, const void* m_end);
private: private:
const void* m_pos; const void* pos_;
const void* m_end; const void* end_;
}; };
......
...@@ -34,30 +34,26 @@ ...@@ -34,30 +34,26 @@
namespace caf { namespace caf {
/** /// Implements the serializer interface with a binary serialization protocol.
* Implements the serializer interface with a binary serialization protocol.
*/
class binary_serializer : public serializer { class binary_serializer : public serializer {
using super = serializer; using super = serializer;
public: public:
using write_fun = std::function<void(const char*, const char*)>; using write_fun = std::function<void(const char*, const char*)>;
/** /// Creates a binary serializer writing to given iterator position.
* Creates a binary serializer writing to given iterator position.
*/
template <class OutIter> template <class OutIter>
binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) { binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) {
struct fun { struct fun {
fun(OutIter pos) : m_pos(pos) {} fun(OutIter pos) : pos_(pos) {}
void operator()(const char* first, const char* last) { void operator()(const char* first, const char* last) {
m_pos = std::copy(first, last, m_pos); pos_ = std::copy(first, last, pos_);
} }
OutIter m_pos; OutIter pos_;
}; };
m_out = fun{iter}; out_ = fun{iter};
} }
void begin_object(const uniform_type_info* uti) override; void begin_object(const uniform_type_info* uti) override;
...@@ -72,9 +68,9 @@ class binary_serializer : public serializer { ...@@ -72,9 +68,9 @@ class binary_serializer : public serializer {
void write_raw(size_t num_bytes, const void* data) override; void write_raw(size_t num_bytes, const void* data) override;
private: private:
write_fun m_out; write_fun out_;
}; };
......
...@@ -39,15 +39,13 @@ ...@@ -39,15 +39,13 @@
namespace caf { namespace caf {
/** /// A thread-mapped or context-switching actor using a blocking
* A thread-mapped or context-switching actor using a blocking /// receive rather than a behavior-stack based message processing.
* receive rather than a behavior-stack based message processing. /// @extends local_actor
* @extends local_actor
*/
class blocking_actor class blocking_actor
: public extend<local_actor, blocking_actor>:: : public extend<local_actor, blocking_actor>::
with<mixin::sync_sender<blocking_response_handle_tag>::impl> { with<mixin::sync_sender<blocking_response_handle_tag>::impl> {
public: public:
class functor_based; class functor_based;
blocking_actor(); blocking_actor();
...@@ -61,39 +59,39 @@ class blocking_actor ...@@ -61,39 +59,39 @@ class blocking_actor
using timeout_type = std::chrono::high_resolution_clock::time_point; using timeout_type = std::chrono::high_resolution_clock::time_point;
struct receive_while_helper { struct receive_while_helper {
std::function<void(behavior&)> m_dq; std::function<void(behavior&)> dq_;
std::function<bool()> m_stmt; std::function<bool()> stmt_;
template <class... Ts> template <class... Ts>
void operator()(Ts&&... xs) { void operator()(Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, static_assert(sizeof...(Ts) > 0,
"operator() requires at least one argument"); "operator() requires at least one argument");
behavior bhvr{std::forward<Ts>(xs)...}; behavior bhvr{std::forward<Ts>(xs)...};
while (m_stmt()) m_dq(bhvr); while (stmt_()) dq_(bhvr);
} }
}; };
template <class T> template <class T>
struct receive_for_helper { struct receive_for_helper {
std::function<void(behavior&)> m_dq; std::function<void(behavior&)> dq_;
T& begin; T& begin;
T end; T end;
template <class... Ts> template <class... Ts>
void operator()(Ts&&... xs) { void operator()(Ts&&... xs) {
behavior bhvr{std::forward<Ts>(xs)...}; behavior bhvr{std::forward<Ts>(xs)...};
for (; begin != end; ++begin) m_dq(bhvr); for (; begin != end; ++begin) dq_(bhvr);
} }
}; };
struct do_receive_helper { struct do_receive_helper {
std::function<void(behavior&)> m_dq; std::function<void(behavior&)> dq_;
behavior m_bhvr; behavior bhvr_;
template <class Statement> template <class Statement>
void until(Statement stmt) { void until(Statement stmt) {
do { do {
m_dq(m_bhvr); dq_(bhvr_);
} while (stmt() == false); } while (stmt() == false);
} }
...@@ -102,10 +100,8 @@ class blocking_actor ...@@ -102,10 +100,8 @@ class blocking_actor
} }
}; };
/** /// Dequeues the next message from the mailbox that is
* Dequeues the next message from the mailbox that is /// matched by given behavior.
* matched by given behavior.
*/
template <class... Ts> template <class... Ts>
void receive(Ts&&... xs) { void receive(Ts&&... xs) {
static_assert(sizeof...(Ts), "at least one argument required"); static_assert(sizeof...(Ts), "at least one argument required");
...@@ -113,50 +109,44 @@ class blocking_actor ...@@ -113,50 +109,44 @@ class blocking_actor
dequeue(bhvr); dequeue(bhvr);
} }
/** /// Semantically equal to: `for (;;) { receive(...); }`, but does
* Semantically equal to: `for (;;) { receive(...); }`, but does /// not cause a temporary behavior object per iteration.
* not cause a temporary behavior object per iteration.
*/
template <class... Ts> template <class... Ts>
void receive_loop(Ts&&... xs) { void receive_loop(Ts&&... xs) {
behavior bhvr{std::forward<Ts>(xs)...}; behavior bhvr{std::forward<Ts>(xs)...};
for (;;) dequeue(bhvr); for (;;) dequeue(bhvr);
} }
/** /// Receives messages for range `[begin, first)`.
* Receives messages for range `[begin, first)`. /// Semantically equal to:
* Semantically equal to: /// `for ( ; begin != end; ++begin) { receive(...); }`.
* `for ( ; begin != end; ++begin) { receive(...); }`. ///
* /// **Usage example:**
* **Usage example:** /// ~~~
* ~~~ /// int i = 0;
* int i = 0; /// receive_for(i, 10) (
* receive_for(i, 10) ( /// [&](get_atom) {
* [&](get_atom) { /// return i;
* return i; /// }
* } /// );
* ); /// ~~~
* ~~~
*/
template <class T> template <class T>
receive_for_helper<T> receive_for(T& begin, const T& end) { receive_for_helper<T> receive_for(T& begin, const T& end) {
return {make_dequeue_callback(), begin, end}; return {make_dequeue_callback(), begin, end};
} }
/** /// Receives messages as long as `stmt` returns true.
* Receives messages as long as `stmt` returns true. /// Semantically equal to: `while (stmt()) { receive(...); }`.
* Semantically equal to: `while (stmt()) { receive(...); }`. ///
* /// **Usage example:**
* **Usage example:** /// ~~~
* ~~~ /// int i = 0;
* int i = 0; /// receive_while([&]() { return (++i <= 10); })
* receive_while([&]() { return (++i <= 10); }) /// (
* ( /// on<int>() >> int_fun,
* on<int>() >> int_fun, /// on<float>() >> float_fun
* on<float>() >> float_fun /// );
* ); /// ~~~
* ~~~
*/
template <class Statement> template <class Statement>
receive_while_helper receive_while(Statement stmt) { receive_while_helper receive_while(Statement stmt) {
static_assert(std::is_same<bool, decltype(stmt())>::value, static_assert(std::is_same<bool, decltype(stmt())>::value,
...@@ -164,47 +154,41 @@ class blocking_actor ...@@ -164,47 +154,41 @@ class blocking_actor
return {make_dequeue_callback(), stmt}; return {make_dequeue_callback(), stmt};
} }
/** /// Receives messages until `stmt` returns true.
* Receives messages until `stmt` returns true. ///
* /// Semantically equal to:
* Semantically equal to: /// `do { receive(...); } while (stmt() == false);`
* `do { receive(...); } while (stmt() == false);` ///
* /// **Usage example:**
* **Usage example:** /// ~~~
* ~~~ /// int i = 0;
* int i = 0; /// do_receive
* do_receive /// (
* ( /// on<int>() >> int_fun,
* on<int>() >> int_fun, /// on<float>() >> float_fun
* on<float>() >> float_fun /// )
* ) /// .until([&]() { return (++i >= 10); };
* .until([&]() { return (++i >= 10); }; /// ~~~
* ~~~
*/
template <class... Ts> template <class... Ts>
do_receive_helper do_receive(Ts&&... xs) { do_receive_helper do_receive(Ts&&... xs) {
return {make_dequeue_callback(), behavior{std::forward<Ts>(xs)...}}; return {make_dequeue_callback(), behavior{std::forward<Ts>(xs)...}};
} }
/** /// Blocks this actor until all other actors are done.
* Blocks this actor until all other actors are done.
*/
void await_all_other_actors_done(); void await_all_other_actors_done();
/** /// Implements the actor's behavior.
* Implements the actor's behavior.
*/
virtual void act() = 0; virtual void act() = 0;
/** @cond PRIVATE */ /// @cond PRIVATE
void initialize() override; void initialize() override;
void dequeue(behavior& bhvr, message_id mid = invalid_message_id); void dequeue(behavior& bhvr, message_id mid = invalid_message_id);
/** @endcond */ /// @endcond
protected: protected:
// helper function to implement receive_(for|while) and do_receive // helper function to implement receive_(for|while) and do_receive
std::function<void(behavior&)> make_dequeue_callback() { std::function<void(behavior&)> make_dequeue_callback() {
return [=](behavior& bhvr) { dequeue(bhvr); }; return [=](behavior& bhvr) { dequeue(bhvr); };
...@@ -212,7 +196,7 @@ class blocking_actor ...@@ -212,7 +196,7 @@ class blocking_actor
}; };
class blocking_actor::functor_based : public blocking_actor { class blocking_actor::functor_based : public blocking_actor {
public: public:
using act_fun = std::function<void(blocking_actor*)>; using act_fun = std::function<void(blocking_actor*)>;
template <class F, class... Ts> template <class F, class... Ts>
...@@ -226,10 +210,10 @@ class blocking_actor::functor_based : public blocking_actor { ...@@ -226,10 +210,10 @@ class blocking_actor::functor_based : public blocking_actor {
void cleanup(uint32_t reason); void cleanup(uint32_t reason);
protected: protected:
void act() override; void act() override;
private: private:
void create(blocking_actor*, act_fun); void create(blocking_actor*, act_fun);
template <class Actor, typename F, class... Ts> template <class Actor, typename F, class... Ts>
...@@ -243,7 +227,7 @@ class blocking_actor::functor_based : public blocking_actor { ...@@ -243,7 +227,7 @@ class blocking_actor::functor_based : public blocking_actor {
create(dummy, [fun](Actor*) { fun(); }); create(dummy, [fun](Actor*) { fun(); });
} }
act_fun m_act; act_fun act_;
}; };
} // namespace caf } // namespace caf
......
...@@ -39,13 +39,11 @@ class execution_unit; ...@@ -39,13 +39,11 @@ class execution_unit;
struct invalid_actor_t; struct invalid_actor_t;
struct invalid_group_t; struct invalid_group_t;
/** /// A handle to instances of `abstract_channel`.
* A handle to instances of `abstract_channel`.
*/
class channel : detail::comparable<channel>, class channel : detail::comparable<channel>,
detail::comparable<channel, actor>, detail::comparable<channel, actor>,
detail::comparable<channel, abstract_channel*> { detail::comparable<channel, abstract_channel*> {
public: public:
template <class T, typename U> template <class T, typename U>
friend T actor_cast(const U&); friend T actor_cast(const U&);
...@@ -64,26 +62,26 @@ class channel : detail::comparable<channel>, ...@@ -64,26 +62,26 @@ class channel : detail::comparable<channel>,
typename std::enable_if< typename std::enable_if<
std::is_base_of<abstract_channel, T>::value std::is_base_of<abstract_channel, T>::value
>::type* = 0) >::type* = 0)
: m_ptr(ptr) { : ptr_(ptr) {
// nop // nop
} }
channel(abstract_channel* ptr); channel(abstract_channel* ptr);
inline explicit operator bool() const { inline explicit operator bool() const {
return static_cast<bool>(m_ptr); return static_cast<bool>(ptr_);
} }
inline bool operator!() const { inline bool operator!() const {
return !m_ptr; return ! ptr_;
} }
inline abstract_channel* operator->() const { inline abstract_channel* operator->() const {
return m_ptr.get(); return ptr_.get();
} }
inline abstract_channel& operator*() const { inline abstract_channel& operator*() const {
return *m_ptr; return *ptr_;
} }
intptr_t compare(const channel& other) const; intptr_t compare(const channel& other) const;
...@@ -95,12 +93,12 @@ class channel : detail::comparable<channel>, ...@@ -95,12 +93,12 @@ class channel : detail::comparable<channel>,
static intptr_t compare(const abstract_channel* lhs, static intptr_t compare(const abstract_channel* lhs,
const abstract_channel* rhs); const abstract_channel* rhs);
private: private:
inline abstract_channel* get() const { inline abstract_channel* get() const {
return m_ptr.get(); return ptr_.get();
} }
abstract_channel_ptr m_ptr; abstract_channel_ptr ptr_;
}; };
} // namespace caf } // namespace caf
......
...@@ -27,10 +27,8 @@ ...@@ -27,10 +27,8 @@
namespace caf { namespace caf {
/** /// Checks whether `R` does support an input of type `{Ts...}` via a
* Checks whether `R` does support an input of type `{Ts...}` via a /// static assertion (always returns 0).
* static assertion (always returns 0).
*/
template <class... Sigs, class... Ts> template <class... Sigs, class... Ts>
void check_typed_input(const typed_actor<Sigs...>&, void check_typed_input(const typed_actor<Sigs...>&,
const detail::type_list<Ts...>&) { const detail::type_list<Ts...>&) {
......
...@@ -29,26 +29,23 @@ ...@@ -29,26 +29,23 @@
// - denotes the amount of logging, ranging from error messages only (0) // - denotes the amount of logging, ranging from error messages only (0)
// to complete traces (4) // to complete traces (4)
/** /// Denotes version of CAF in the format {MAJOR}{MINOR}{PATCH},
* Denotes version of CAF in the format {MAJOR}{MINOR}{PATCH}, /// whereas each number is a two-digit decimal number without
* whereas each number is a two-digit decimal number without /// leading zeros (e.g. 900 is version 0.9.0).
* leading zeros (e.g. 900 is version 0.9.0).
*/
#define CAF_VERSION 1302 #define CAF_VERSION 1302
/** /// Defined to the major version number of CAF.
* Defined to the major version number of CAF. ///*/
**/
#define CAF_MAJOR_VERSION (CAF_VERSION / 10000) #define CAF_MAJOR_VERSION (CAF_VERSION / 10000)
/** /**
* Defined to the minor version number of CAF. /// Defined to the minor version number of CAF.
**/ ///*/
#define CAF_MINOR_VERSION ((CAF_VERSION / 100) % 100) #define CAF_MINOR_VERSION ((CAF_VERSION / 100) % 100)
/** /**
* Defined to the patch version number of CAF. /// Defined to the patch version number of CAF.
**/ ///*/
#define CAF_PATCH_VERSION (CAF_VERSION % 100) #define CAF_PATCH_VERSION (CAF_VERSION % 100)
// This compiler-specific block defines: // This compiler-specific block defines:
......
...@@ -31,24 +31,20 @@ namespace caf { ...@@ -31,24 +31,20 @@ namespace caf {
class local_actor; class local_actor;
/** /// Helper class to enable users to add continuations
* Helper class to enable users to add continuations /// when dealing with synchronous sends.
* when dealing with synchronous sends.
*/
class continue_helper { class continue_helper {
public: public:
using message_id_wrapper_tag = int; using message_id_wrapper_tag = int;
continue_helper(message_id mid); continue_helper(message_id mid);
/** /// Returns the ID of the expected response message.
* Returns the ID of the expected response message.
*/
message_id get_message_id() const { message_id get_message_id() const {
return m_mid; return mid_;
} }
private: private:
message_id m_mid; message_id mid_;
}; };
} // namespace caf } // namespace caf
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
namespace caf { namespace caf {
class default_attachable : public attachable { class default_attachable : public attachable {
public: public:
enum observe_type { enum observe_type {
monitor, monitor,
link link
...@@ -53,24 +53,24 @@ class default_attachable : public attachable { ...@@ -53,24 +53,24 @@ class default_attachable : public attachable {
class predicate { class predicate {
public: public:
inline predicate(actor_addr observer, observe_type type) inline predicate(actor_addr observer, observe_type type)
: m_observer(std::move(observer)), : observer_(std::move(observer)),
m_type(type) { type_(type) {
// nop // nop
} }
inline bool operator()(const attachable_ptr& ptr) const { inline bool operator()(const attachable_ptr& ptr) const {
return ptr->matches(observe_token{m_observer, m_type}); return ptr->matches(observe_token{observer_, type_});
} }
private: private:
actor_addr m_observer; actor_addr observer_;
observe_type m_type; observe_type type_;
}; };
private: private:
default_attachable(actor_addr observer, observe_type type); default_attachable(actor_addr observer, observe_type type);
actor_addr m_observer; actor_addr observer_;
observe_type m_type; observe_type type_;
}; };
} // namespace caf } // namespace caf
......
...@@ -31,51 +31,37 @@ namespace caf { ...@@ -31,51 +31,37 @@ namespace caf {
class actor_namespace; class actor_namespace;
class uniform_type_info; class uniform_type_info;
/** /// @ingroup TypeSystem
* @ingroup TypeSystem /// Technology-independent deserialization interface.
* Technology-independent deserialization interface.
*/
class deserializer { class deserializer {
deserializer(const deserializer&) = delete; deserializer(const deserializer&) = delete;
deserializer& operator=(const deserializer&) = delete; deserializer& operator=(const deserializer&) = delete;
public: public:
deserializer(actor_namespace* ns = nullptr); deserializer(actor_namespace* ns = nullptr);
virtual ~deserializer(); virtual ~deserializer();
/** /// Begins deserialization of a new object.
* Begins deserialization of a new object.
*/
virtual const uniform_type_info* begin_object() = 0; virtual const uniform_type_info* begin_object() = 0;
/** /// Ends deserialization of an object.
* Ends deserialization of an object.
*/
virtual void end_object() = 0; virtual void end_object() = 0;
/** /// Begins deserialization of a sequence.
* Begins deserialization of a sequence. /// @returns The size of the sequence.
* @returns The size of the sequence.
*/
virtual size_t begin_sequence() = 0; virtual size_t begin_sequence() = 0;
/** /// Ends deserialization of a sequence.
* Ends deserialization of a sequence.
*/
virtual void end_sequence() = 0; virtual void end_sequence() = 0;
/** /// Reads a primitive value from the data source.
* Reads a primitive value from the data source.
*/
virtual void read_value(primitive_variant& storage) = 0; virtual void read_value(primitive_variant& storage) = 0;
/** /// Reads a value of type `T` from the data source.
* Reads a value of type `T` from the data source. /// @note `T` must be a primitive type.
* @note `T` must be a primitive type.
*/
template <class T> template <class T>
inline T read() { inline T read() {
primitive_variant val{T()}; primitive_variant val{T()};
...@@ -104,13 +90,11 @@ class deserializer { ...@@ -104,13 +90,11 @@ class deserializer {
return *this; return *this;
} }
/** /// Reads a raw memory block.
* Reads a raw memory block.
*/
virtual void read_raw(size_t num_bytes, void* storage) = 0; virtual void read_raw(size_t num_bytes, void* storage) = 0;
inline actor_namespace* get_namespace() { inline actor_namespace* get_namespace() {
return m_namespace; return namespace_;
} }
template <class Buffer> template <class Buffer>
...@@ -119,8 +103,8 @@ class deserializer { ...@@ -119,8 +103,8 @@ class deserializer {
read_raw(num_bytes, storage.data()); read_raw(num_bytes, storage.data());
} }
private: private:
actor_namespace* m_namespace; actor_namespace* namespace_;
}; };
} // namespace caf } // namespace caf
......
...@@ -31,15 +31,13 @@ ...@@ -31,15 +31,13 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
/** /// Implements all pure virtual functions of `uniform_type_info`
* Implements all pure virtual functions of `uniform_type_info` /// except serialize() and deserialize().
* except serialize() and deserialize().
*/
template <class T> template <class T>
class abstract_uniform_type_info : public uniform_type_info { class abstract_uniform_type_info : public uniform_type_info {
public: public:
const char* name() const override { const char* name() const override {
return m_name.c_str(); return name_.c_str();
} }
message as_message(void* instance) const override { message as_message(void* instance) const override {
...@@ -47,7 +45,7 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -47,7 +45,7 @@ class abstract_uniform_type_info : public uniform_type_info {
} }
bool equal_to(const std::type_info& tinfo) const override { bool equal_to(const std::type_info& tinfo) const override {
return m_native == &tinfo || *m_native == tinfo; return native_ == &tinfo || *native_ == tinfo;
} }
bool equals(const void* lhs, const void* rhs) const override { bool equals(const void* lhs, const void* rhs) const override {
...@@ -58,10 +56,10 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -58,10 +56,10 @@ class abstract_uniform_type_info : public uniform_type_info {
return create_impl<T>(other); return create_impl<T>(other);
} }
protected: protected:
abstract_uniform_type_info(std::string tname) abstract_uniform_type_info(std::string tname)
: m_name(std::move(tname)), : name_(std::move(tname)),
m_native(&typeid(T)) { native_(&typeid(T)) {
// nop // nop
} }
...@@ -79,10 +77,10 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -79,10 +77,10 @@ class abstract_uniform_type_info : public uniform_type_info {
return false; return false;
} }
std::string m_name; std::string name_;
const std::type_info* m_native; const std::type_info* native_;
private: private:
template <class C> template <class C>
typename std::enable_if<std::is_empty<C>::value, bool>::type typename std::enable_if<std::is_empty<C>::value, bool>::type
eq(const C&, const C&) const { eq(const C&, const C&) const {
...@@ -90,7 +88,7 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -90,7 +88,7 @@ class abstract_uniform_type_info : public uniform_type_info {
} }
template <class C> template <class C>
typename std::enable_if<!std::is_empty<C>::value && typename std::enable_if<! std::is_empty<C>::value &&
detail::is_comparable<C, C>::value, detail::is_comparable<C, C>::value,
bool>::type bool>::type
eq(const C& lhs, const C& rhs) const { eq(const C& lhs, const C& rhs) const {
...@@ -98,8 +96,8 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -98,8 +96,8 @@ class abstract_uniform_type_info : public uniform_type_info {
} }
template <class C> template <class C>
typename std::enable_if<!std::is_empty<C>::value && std::is_pod<C>::value && typename std::enable_if<! std::is_empty<C>::value && std::is_pod<C>::value &&
!detail::is_comparable<C, C>::value, ! detail::is_comparable<C, C>::value,
bool>::type bool>::type
eq(const C& lhs, const C& rhs) const { eq(const C& lhs, const C& rhs) const {
return pod_mems_equals(lhs, rhs); return pod_mems_equals(lhs, rhs);
......
...@@ -38,16 +38,14 @@ namespace detail { ...@@ -38,16 +38,14 @@ namespace detail {
class singletons; class singletons;
class actor_registry : public singleton_mixin<actor_registry> { class actor_registry : public singleton_mixin<actor_registry> {
public: public:
friend class singleton_mixin<actor_registry>; friend class singleton_mixin<actor_registry>;
~actor_registry(); ~actor_registry();
/** /// A registry entry consists of a pointer to the actor and an
* A registry entry consists of a pointer to the actor and an /// exit reason. An entry with a nullptr means the actor has finished
* exit reason. An entry with a nullptr means the actor has finished /// execution for given reason.
* execution for given reason.
*/
using value_type = std::pair<abstract_actor_ptr, uint32_t>; using value_type = std::pair<abstract_actor_ptr, uint32_t>;
value_type get_entry(actor_id key) const; value_type get_entry(actor_id key) const;
...@@ -75,19 +73,19 @@ class actor_registry : public singleton_mixin<actor_registry> { ...@@ -75,19 +73,19 @@ class actor_registry : public singleton_mixin<actor_registry> {
// blocks the caller until running-actors-count becomes `expected` // blocks the caller until running-actors-count becomes `expected`
void await_running_count_equal(size_t expected); void await_running_count_equal(size_t expected);
private: private:
using entries = std::map<actor_id, value_type>; using entries = std::map<actor_id, value_type>;
actor_registry(); actor_registry();
std::atomic<size_t> m_running; std::atomic<size_t> running_;
std::atomic<actor_id> m_ids; std::atomic<actor_id> ids_;
std::mutex m_running_mtx; std::mutex running_mtx_;
std::condition_variable m_running_cv; std::condition_variable running_cv_;
mutable detail::shared_spinlock m_instances_mtx; mutable detail::shared_spinlock instances_mtx_;
entries m_entries; entries entries_;
}; };
} // namespace detail } // namespace detail
......
...@@ -63,7 +63,7 @@ struct has_skip_message { ...@@ -63,7 +63,7 @@ struct has_skip_message {
}; };
class behavior_impl : public ref_counted { class behavior_impl : public ref_counted {
public: public:
using pointer = intrusive_ptr<behavior_impl>; using pointer = intrusive_ptr<behavior_impl>;
~behavior_impl(); ~behavior_impl();
...@@ -80,17 +80,17 @@ class behavior_impl : public ref_counted { ...@@ -80,17 +80,17 @@ class behavior_impl : public ref_counted {
virtual void handle_timeout(); virtual void handle_timeout();
inline const duration& timeout() const { inline const duration& timeout() const {
return m_timeout; return timeout_;
} }
virtual pointer copy(const generic_timeout_definition& tdef) const = 0; virtual pointer copy(const generic_timeout_definition& tdef) const = 0;
pointer or_else(const pointer& other); pointer or_else(const pointer& other);
protected: protected:
duration m_timeout; duration timeout_;
match_case_info* m_begin; match_case_info* begin_;
match_case_info* m_end; match_case_info* end_;
}; };
template <size_t Pos, size_t Size> template <size_t Pos, size_t Size>
...@@ -116,40 +116,40 @@ struct defaut_bhvr_impl_init<Size, Size> { ...@@ -116,40 +116,40 @@ struct defaut_bhvr_impl_init<Size, Size> {
template <class Tuple> template <class Tuple>
class default_behavior_impl : public behavior_impl { class default_behavior_impl : public behavior_impl {
public: public:
static constexpr size_t num_cases = std::tuple_size<Tuple>::value; static constexpr size_t num_cases = std::tuple_size<Tuple>::value;
default_behavior_impl(Tuple tup) : m_cases(std::move(tup)) { default_behavior_impl(Tuple tup) : cases_(std::move(tup)) {
init(); init();
} }
template <class F> template <class F>
default_behavior_impl(Tuple tup, timeout_definition<F> d) default_behavior_impl(Tuple tup, timeout_definition<F> d)
: behavior_impl(d.timeout), : behavior_impl(d.timeout),
m_cases(std::move(tup)), cases_(std::move(tup)),
m_fun(d.handler) { fun_(d.handler) {
init(); init();
} }
typename behavior_impl::pointer typename behavior_impl::pointer
copy(const generic_timeout_definition& tdef) const override { copy(const generic_timeout_definition& tdef) const override {
return make_counted<default_behavior_impl<Tuple>>(m_cases, tdef); return make_counted<default_behavior_impl<Tuple>>(cases_, tdef);
} }
void handle_timeout() override { void handle_timeout() override {
m_fun(); fun_();
} }
private: private:
void init() { void init() {
defaut_bhvr_impl_init<0, num_cases>::init(m_arr, m_cases); defaut_bhvr_impl_init<0, num_cases>::init(arr_, cases_);
m_begin = m_arr.data(); begin_ = arr_.data();
m_end = m_begin + m_arr.size(); end_ = begin_ + arr_.size();
} }
Tuple m_cases; Tuple cases_;
std::array<match_case_info, num_cases> m_arr; std::array<match_case_info, num_cases> arr_;
std::function<void()> m_fun; std::function<void()> fun_;
}; };
// eor = end of recursion // eor = end of recursion
...@@ -216,7 +216,7 @@ intrusive_ptr<R> make_behavior_ra(tail_argument_token&, Ts&... xs) { ...@@ -216,7 +216,7 @@ intrusive_ptr<R> make_behavior_ra(tail_argument_token&, Ts&... xs) {
// for some reason, this call is ambigious on GCC without enable_if // for some reason, this call is ambigious on GCC without enable_if
template <class R, class V, class... Ts> template <class R, class V, class... Ts>
typename std::enable_if< typename std::enable_if<
!std::is_same<V, tail_argument_token>::value, ! std::is_same<V, tail_argument_token>::value,
intrusive_ptr<R> intrusive_ptr<R>
>::type >::type
make_behavior_ra(V& v, Ts&... xs) { make_behavior_ra(V& v, Ts&... xs) {
......
...@@ -38,7 +38,7 @@ namespace detail { ...@@ -38,7 +38,7 @@ namespace detail {
struct behavior_stack_mover; struct behavior_stack_mover;
class behavior_stack { class behavior_stack {
public: public:
friend struct behavior_stack_mover; friend struct behavior_stack_mover;
behavior_stack(const behavior_stack&) = delete; behavior_stack(const behavior_stack&) = delete;
...@@ -52,25 +52,25 @@ class behavior_stack { ...@@ -52,25 +52,25 @@ class behavior_stack {
void clear(); void clear();
inline bool empty() const { inline bool empty() const {
return m_elements.empty(); return elements_.empty();
} }
inline behavior& back() { inline behavior& back() {
CAF_ASSERT(!empty()); CAF_ASSERT(! empty());
return m_elements.back(); return elements_.back();
} }
inline void push_back(behavior&& what) { inline void push_back(behavior&& what) {
m_elements.emplace_back(std::move(what)); elements_.emplace_back(std::move(what));
} }
inline void cleanup() { inline void cleanup() {
m_erased_elements.clear(); erased_elements_.clear();
} }
private: private:
std::vector<behavior> m_elements; std::vector<behavior> elements_;
std::vector<behavior> m_erased_elements; std::vector<behavior> erased_elements_;
}; };
} // namespace detail } // namespace detail
......
...@@ -23,14 +23,12 @@ ...@@ -23,14 +23,12 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
/** /// Barton–Nackman trick implementation.
* Barton–Nackman trick implementation. /// `Subclass` must provide a compare member function that compares
* `Subclass` must provide a compare member function that compares /// to instances of `T` and returns an integer x with:
* to instances of `T` and returns an integer x with: /// - `x < 0` if `*this < other`
* - `x < 0` if `*this < other` /// - `x > 0` if `*this > other`
* - `x > 0` if `*this > other` /// - `x == 0` if `*this == other`
* - `x == 0` if `*this == other`
*/
template <class Subclass, class T = Subclass> template <class Subclass, class T = Subclass>
class comparable { class comparable {
......
...@@ -29,7 +29,7 @@ namespace caf { ...@@ -29,7 +29,7 @@ namespace caf {
namespace detail { namespace detail {
class concatenated_tuple : public message_data { class concatenated_tuple : public message_data {
public: public:
concatenated_tuple& operator=(const concatenated_tuple&) = delete; concatenated_tuple& operator=(const concatenated_tuple&) = delete;
using message_data::cow_ptr; using message_data::cow_ptr;
...@@ -56,16 +56,16 @@ class concatenated_tuple : public message_data { ...@@ -56,16 +56,16 @@ class concatenated_tuple : public message_data {
concatenated_tuple() = default; concatenated_tuple() = default;
private: private:
concatenated_tuple(const concatenated_tuple&) = default; concatenated_tuple(const concatenated_tuple&) = default;
std::pair<message_data*, size_t> select(size_t pos) const; std::pair<message_data*, size_t> select(size_t pos) const;
void init(); void init();
vector_type m_data; vector_type data_;
uint32_t m_type_token; uint32_t type_token_;
size_t m_size; size_t size_;
}; };
} // namespace detail } // namespace detail
......
...@@ -36,7 +36,7 @@ namespace caf { ...@@ -36,7 +36,7 @@ namespace caf {
namespace detail { namespace detail {
class decorated_tuple : public message_data { class decorated_tuple : public message_data {
public: public:
decorated_tuple& operator=(const decorated_tuple&) = delete; decorated_tuple& operator=(const decorated_tuple&) = delete;
using vector_type = std::vector<size_t>; using vector_type = std::vector<size_t>;
...@@ -66,19 +66,19 @@ class decorated_tuple : public message_data { ...@@ -66,19 +66,19 @@ class decorated_tuple : public message_data {
uint16_t type_nr_at(size_t pos) const override; uint16_t type_nr_at(size_t pos) const override;
inline const cow_ptr& decorated() const { inline const cow_ptr& decorated() const {
return m_decorated; return decorated_;
} }
inline const vector_type& mapping() const { inline const vector_type& mapping() const {
return m_mapping; return mapping_;
} }
private: private:
decorated_tuple(const decorated_tuple&) = default; decorated_tuple(const decorated_tuple&) = default;
cow_ptr m_decorated; cow_ptr decorated_;
vector_type m_mapping; vector_type mapping_;
uint32_t m_type_token; uint32_t type_token_;
}; };
} // namespace detail } // namespace detail
......
...@@ -25,22 +25,22 @@ namespace detail { ...@@ -25,22 +25,22 @@ namespace detail {
class disablable_delete { class disablable_delete {
public: public:
constexpr disablable_delete() : m_enabled(true) {} constexpr disablable_delete() : enabled_(true) {}
inline void disable() { m_enabled = false; } inline void disable() { enabled_ = false; }
inline void enable() { m_enabled = true; } inline void enable() { enabled_ = true; }
template <class T> template <class T>
inline void operator()(T* ptr) { inline void operator()(T* ptr) {
if (m_enabled) delete ptr; if (enabled_) delete ptr;
} }
private: private:
bool m_enabled; bool enabled_;
}; };
......
...@@ -26,7 +26,7 @@ namespace caf { ...@@ -26,7 +26,7 @@ namespace caf {
namespace detail { namespace detail {
class disposer { class disposer {
public: public:
inline void operator()(memory_managed* ptr) const { inline void operator()(memory_managed* ptr) const {
ptr->request_deletion(false); ptr->request_deletion(false);
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <cassert> #include <cassert>
// GCC hack // GCC hack
#if defined(CAF_GCC) && !defined(_GLIBCXX_USE_SCHED_YIELD) #if defined(CAF_GCC) && ! defined(_GLIBCXX_USE_SCHED_YIELD)
#include <time.h> #include <time.h>
namespace std { namespace std {
namespace this_thread { namespace this_thread {
...@@ -47,7 +47,7 @@ inline void yield() noexcept { ...@@ -47,7 +47,7 @@ inline void yield() noexcept {
#endif #endif
// another GCC hack // another GCC hack
#if defined(CAF_GCC) && !defined(_GLIBCXX_USE_NANOSLEEP) #if defined(CAF_GCC) && ! defined(_GLIBCXX_USE_NANOSLEEP)
#include <time.h> #include <time.h>
namespace std { namespace std {
namespace this_thread { namespace this_thread {
...@@ -77,7 +77,7 @@ namespace detail { ...@@ -77,7 +77,7 @@ namespace detail {
*/ */
template <class T> template <class T>
class double_ended_queue { class double_ended_queue {
public: public:
using value_type = T; using value_type = T;
using size_type = size_t; using size_type = size_t;
using difference_type = ptrdiff_t; using difference_type = ptrdiff_t;
...@@ -110,15 +110,15 @@ class double_ended_queue { ...@@ -110,15 +110,15 @@ class double_ended_queue {
"sizeof(node*) >= CAF_CACHE_LINE_SIZE"); "sizeof(node*) >= CAF_CACHE_LINE_SIZE");
double_ended_queue() { double_ended_queue() {
m_head_lock.clear(); head_lock_.clear();
m_tail_lock.clear(); tail_lock_.clear();
auto ptr = new node(nullptr); auto ptr = new node(nullptr);
m_head = ptr; head_ = ptr;
m_tail = ptr; tail_ = ptr;
} }
~double_ended_queue() { ~double_ended_queue() {
auto ptr = m_head.load(); auto ptr = head_.load();
while (ptr) { while (ptr) {
unique_node_ptr tmp{ptr}; unique_node_ptr tmp{ptr};
ptr = tmp->next.load(); ptr = tmp->next.load();
...@@ -129,10 +129,10 @@ class double_ended_queue { ...@@ -129,10 +129,10 @@ class double_ended_queue {
void append(pointer value) { void append(pointer value) {
CAF_ASSERT(value != nullptr); CAF_ASSERT(value != nullptr);
node* tmp = new node(value); node* tmp = new node(value);
lock_guard guard(m_tail_lock); lock_guard guard(tail_lock_);
// publish & swing last forward // publish & swing last forward
m_tail.load()->next = tmp; tail_.load()->next = tmp;
m_tail = tmp; tail_ = tmp;
} }
// acquires both locks // acquires both locks
...@@ -140,20 +140,20 @@ class double_ended_queue { ...@@ -140,20 +140,20 @@ class double_ended_queue {
CAF_ASSERT(value != nullptr); CAF_ASSERT(value != nullptr);
node* tmp = new node(value); node* tmp = new node(value);
node* first = nullptr; node* first = nullptr;
// acquire both locks since we might touch m_last too // acquire both locks since we might touch last_ too
lock_guard guard1(m_head_lock); lock_guard guard1(head_lock_);
lock_guard guard2(m_tail_lock); lock_guard guard2(tail_lock_);
first = m_head.load(); first = head_.load();
CAF_ASSERT(first != nullptr); CAF_ASSERT(first != nullptr);
auto next = first->next.load(); auto next = first->next.load();
// m_first always points to a dummy with no value, // first_ always points to a dummy with no value,
// hence we put the new element second // hence we put the new element second
if (next == nullptr) { if (next == nullptr) {
// queue is empty // queue is empty
CAF_ASSERT(first == m_tail); CAF_ASSERT(first == tail_);
m_tail = tmp; tail_ = tmp;
} else { } else {
CAF_ASSERT(first != m_tail); CAF_ASSERT(first != tail_);
tmp->next = next; tmp->next = next;
} }
first->next = tmp; first->next = tmp;
...@@ -164,8 +164,8 @@ class double_ended_queue { ...@@ -164,8 +164,8 @@ class double_ended_queue {
unique_node_ptr first; unique_node_ptr first;
pointer result = nullptr; pointer result = nullptr;
{ // lifetime scope of guard { // lifetime scope of guard
lock_guard guard(m_head_lock); lock_guard guard(head_lock_);
first.reset(m_head.load()); first.reset(head_.load());
node* next = first->next; node* next = first->next;
if (next == nullptr) { if (next == nullptr) {
// queue is empty // queue is empty
...@@ -175,7 +175,7 @@ class double_ended_queue { ...@@ -175,7 +175,7 @@ class double_ended_queue {
// take it out of the node & swing first forward // take it out of the node & swing first forward
result = next->value; result = next->value;
next->value = nullptr; next->value = nullptr;
m_head = next; head_ = next;
} }
return result; return result;
} }
...@@ -185,18 +185,18 @@ class double_ended_queue { ...@@ -185,18 +185,18 @@ class double_ended_queue {
pointer result = nullptr; pointer result = nullptr;
unique_node_ptr last; unique_node_ptr last;
{ // lifetime scope of guards { // lifetime scope of guards
lock_guard guard1(m_head_lock); lock_guard guard1(head_lock_);
lock_guard guard2(m_tail_lock); lock_guard guard2(tail_lock_);
CAF_ASSERT(m_head != nullptr); CAF_ASSERT(head_ != nullptr);
last.reset(m_tail.load()); last.reset(tail_.load());
if (last.get() == m_head.load()) { if (last.get() == head_.load()) {
last.release(); last.release();
return nullptr; return nullptr;
} }
result = last->value; result = last->value;
m_tail = find_predecessor(last.get()); tail_ = find_predecessor(last.get());
CAF_ASSERT(m_tail != nullptr); CAF_ASSERT(tail_ != nullptr);
m_tail.load()->next = nullptr; tail_.load()->next = nullptr;
} }
return result; return result;
} }
...@@ -204,13 +204,13 @@ class double_ended_queue { ...@@ -204,13 +204,13 @@ class double_ended_queue {
// does not lock // does not lock
bool empty() const { bool empty() const {
// atomically compares first and last pointer without locks // atomically compares first and last pointer without locks
return m_head == m_tail; return head_ == tail_;
} }
private: private:
// precondition: *both* locks acquired // precondition: *both* locks acquired
node* find_predecessor(node* what) { node* find_predecessor(node* what) {
for (auto i = m_head.load(); i != nullptr; i = i->next) { for (auto i = head_.load(); i != nullptr; i = i->next) {
if (i->next == what) { if (i->next == what) {
return i; return i;
} }
...@@ -218,28 +218,28 @@ class double_ended_queue { ...@@ -218,28 +218,28 @@ class double_ended_queue {
return nullptr; return nullptr;
} }
// guarded by m_head_lock // guarded by head_lock_
std::atomic<node*> m_head; std::atomic<node*> head_;
char m_pad1[CAF_CACHE_LINE_SIZE - sizeof(node*)]; char pad1_[CAF_CACHE_LINE_SIZE - sizeof(node*)];
// guarded by m_tail_lock // guarded by tail_lock_
std::atomic<node*> m_tail; std::atomic<node*> tail_;
char m_pad2[CAF_CACHE_LINE_SIZE - sizeof(node*)]; char pad2_[CAF_CACHE_LINE_SIZE - sizeof(node*)];
// enforce exclusive access // enforce exclusive access
std::atomic_flag m_head_lock; std::atomic_flag head_lock_;
std::atomic_flag m_tail_lock; std::atomic_flag tail_lock_;
class lock_guard { class lock_guard {
public: public:
lock_guard(std::atomic_flag& lock) : m_lock(lock) { lock_guard(std::atomic_flag& lock) : lock_(lock) {
while (lock.test_and_set(std::memory_order_acquire)) { while (lock.test_and_set(std::memory_order_acquire)) {
std::this_thread::yield(); std::this_thread::yield();
} }
} }
~lock_guard() { ~lock_guard() {
m_lock.clear(std::memory_order_release); lock_.clear(std::memory_order_release);
} }
private: private:
std::atomic_flag& m_lock; std::atomic_flag& lock_;
}; };
}; };
......
...@@ -28,11 +28,11 @@ namespace detail { ...@@ -28,11 +28,11 @@ namespace detail {
template <class Base> template <class Base>
class embedded final : public Base { class embedded final : public Base {
public: public:
template <class... Ts> template <class... Ts>
embedded(intrusive_ptr<ref_counted> storage, Ts&&... xs) embedded(intrusive_ptr<ref_counted> storage, Ts&&... xs)
: Base(std::forward<Ts>(xs)...), : Base(std::forward<Ts>(xs)...),
m_storage(std::move(storage)) { storage_(std::move(storage)) {
// nop // nop
} }
...@@ -42,14 +42,14 @@ class embedded final : public Base { ...@@ -42,14 +42,14 @@ class embedded final : public Base {
void request_deletion(bool) noexcept override { void request_deletion(bool) noexcept override {
intrusive_ptr<ref_counted> guard; intrusive_ptr<ref_counted> guard;
guard.swap(m_storage); guard.swap(storage_);
// this code assumes that embedded is part of pair_storage<>, // this code assumes that embedded is part of pair_storage<>,
// i.e., this object lives inside a union! // i.e., this object lives inside a union!
this->~embedded(); this->~embedded();
} }
protected: protected:
intrusive_ptr<ref_counted> m_storage; intrusive_ptr<ref_counted> storage_;
}; };
} // namespace detail } // namespace detail
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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