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

Reformatted according to new coding style

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