Commit aa9f724f authored by Dominik Charousset's avatar Dominik Charousset

removed post_office and mailman files (replaced by new middleman implementation)

parent b876e4cc
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_MAILMAN_HPP
#define CPPA_MAILMAN_HPP
#include "cppa/any_tuple.hpp"
#include "cppa/actor_proxy.hpp"
#include "cppa/process_information.hpp"
#include "cppa/util/acceptor.hpp"
#include "cppa/detail/network_manager.hpp"
#include "cppa/detail/singleton_manager.hpp"
#include "cppa/detail/addressed_message.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
namespace cppa { namespace detail {
enum class mm_message_type {
outgoing_message,
add_peer,
shutdown
};
struct mm_message {
mm_message* next;
mm_message_type type;
union {
std::pair<process_information_ptr, addressed_message> out_msg;
std::pair<util::io_stream_ptr_pair, process_information_ptr> peer;
};
mm_message();
mm_message(process_information_ptr, addressed_message);
mm_message(util::io_stream_ptr_pair, process_information_ptr);
~mm_message();
template<typename... Args>
static inline std::unique_ptr<mm_message> create(Args&&... args) {
return std::unique_ptr<mm_message>(new mm_message(std::forward<Args>(args)...));
}
};
void mailman_loop(intrusive::single_reader_queue<mm_message>& q);
template<typename... Args>
inline void send2mm(Args&&... args) {
auto nm = singleton_manager::get_network_manager();
nm->send_to_mailman(mm_message::create(std::forward<Args>(args)...));
}
inline void mailman_enqueue(process_information_ptr peer,
addressed_message outgoing_message) {
send2mm(std::move(peer), std::move(outgoing_message));
}
inline void mailman_add_peer(util::io_stream_ptr_pair peer_streams,
process_information_ptr peer_ptr ) {
send2mm(std::move(peer_streams), std::move(peer_ptr));
}
}} // namespace cppa::detail
#endif // CPPA_MAILMAN_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_POST_OFFICE_HPP
#define CPPA_POST_OFFICE_HPP
#include <memory>
#include <utility>
#include "cppa/atom.hpp"
#include "cppa/actor_proxy.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
#include "cppa/util/acceptor.hpp"
#include "cppa/util/io_stream.hpp"
#include "cppa/detail/network_manager.hpp"
#include "cppa/detail/singleton_manager.hpp"
namespace cppa { namespace detail {
enum class po_message_type {
add_peer,
rm_peer,
publish,
unpublish,
shutdown
};
struct po_message {
po_message* next;
const po_message_type type;
union {
std::pair<util::io_stream_ptr_pair, process_information_ptr> new_peer;
util::io_stream_ptr_pair peer_streams;
std::pair<std::unique_ptr<util::acceptor>, actor_ptr> new_published_actor;
actor_ptr published_actor;
};
po_message();
po_message(util::io_stream_ptr_pair, process_information_ptr);
po_message(util::io_stream_ptr_pair);
po_message(std::unique_ptr<util::acceptor>, actor_ptr);
po_message(actor_ptr);
~po_message();
template<typename... Args>
static inline std::unique_ptr<po_message> create(Args&&... args) {
return std::unique_ptr<po_message>(new po_message(std::forward<Args>(args)...));
}
};
typedef intrusive::single_reader_queue<po_message> po_message_queue;
void post_office_loop(int input_fd, po_message_queue&);
template<typename... Args>
inline void send2po(Args&&... args) {
auto nm = singleton_manager::get_network_manager();
nm->send_to_post_office(po_message::create(std::forward<Args>(args)...));
}
inline void post_office_add_peer(util::io_stream_ptr_pair peer_streams,
process_information_ptr peer_ptr ) {
send2po(std::move(peer_streams), std::move(peer_ptr));
}
inline void post_office_close_peer_connection(util::io_stream_ptr_pair peer_streams) {
send2po(std::move(peer_streams));
}
inline void post_office_publish(std::unique_ptr<util::acceptor> server,
actor_ptr published_actor ) {
send2po(std::move(server), std::move(published_actor));
}
inline void post_office_unpublish(actor_ptr whom) {
send2po(std::move(whom));
}
} } // namespace cppa::detail
#endif // CPPA_POST_OFFICE_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef POST_OFFICE_MSG_HPP
#define POST_OFFICE_MSG_HPP
#include "cppa/attachable.hpp"
#include "cppa/actor_proxy.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/process_information.hpp"
#include "cppa/detail/native_socket.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
namespace cppa { namespace detail {
class post_office_msg {
friend class intrusive::singly_linked_list<post_office_msg>;
friend class intrusive::single_reader_queue<post_office_msg>;
public:
enum msg_type {
invalid_type,
add_peer_type,
add_server_socket_type,
proxy_exited_type
};
struct add_peer {
native_socket_type sockfd;
process_information_ptr peer;
actor_proxy_ptr first_peer_actor;
std::unique_ptr<attachable> attachable_ptr;
add_peer(native_socket_type peer_socket,
const process_information_ptr& peer_ptr,
const actor_proxy_ptr& peer_actor_ptr,
std::unique_ptr<attachable>&& peer_observer);
};
struct add_server_socket {
native_socket_type server_sockfd;
actor_ptr published_actor;
add_server_socket(native_socket_type ssockfd, const actor_ptr& whom);
};
struct proxy_exited {
actor_proxy_ptr proxy_ptr;
inline proxy_exited(const actor_proxy_ptr& who) : proxy_ptr(who) { }
};
inline post_office_msg() : next(nullptr), m_type(invalid_type) { }
post_office_msg(native_socket_type arg0,
const process_information_ptr& arg1,
const actor_proxy_ptr& arg2,
std::unique_ptr<attachable>&& arg3);
post_office_msg(native_socket_type arg0, const actor_ptr& arg1);
post_office_msg(const actor_proxy_ptr& proxy_ptr);
inline bool is_add_peer_msg() const {
return m_type == add_peer_type;
}
inline bool is_add_server_socket_msg() const {
return m_type == add_server_socket_type;
}
inline bool is_proxy_exited_msg() const {
return m_type == proxy_exited_type;
}
inline add_peer& as_add_peer_msg() {
return m_add_peer_msg;
}
inline add_server_socket& as_add_server_socket_msg() {
return m_add_server_socket;
}
inline proxy_exited& as_proxy_exited_msg() {
return m_proxy_exited;
}
~post_office_msg();
private:
post_office_msg* next;
msg_type m_type;
union {
add_peer m_add_peer_msg;
add_server_socket m_add_server_socket;
proxy_exited m_proxy_exited;
};
};
constexpr std::uint32_t rd_queue_event = 0x00;
constexpr std::uint32_t unpublish_actor_event = 0x01;
constexpr std::uint32_t close_socket_event = 0x02;
constexpr std::uint32_t shutdown_event = 0x03;
typedef std::uint32_t pipe_msg[2];
constexpr size_t pipe_msg_size = 2 * sizeof(std::uint32_t);
} } // namespace cppa::detail
#endif // POST_OFFICE_MSG_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include <atomic>
#include <iostream>
#ifdef CPPA_WINDOWS
#else
# include <netdb.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <fcntl.h>
#endif
#include "cppa/cppa.hpp"
#include "cppa/to_string.hpp"
#include "cppa/detail/mailman.hpp"
#include "cppa/binary_serializer.hpp"
#include "cppa/detail/post_office.hpp"
#define DEBUG(arg) \
std::cout << "[process id: " \
<< cppa::process_information::get()->process_id() \
<< "] " << arg << std::endl
#undef DEBUG
#define DEBUG(unused) ((void) 0)
using std::cout;
using std::cerr;
using std::endl;
// implementation of mailman.hpp
namespace cppa { namespace detail {
namespace {
template<typename T, typename... Args>
void call_ctor(T& var, Args&&... args) {
new (&var) T (std::forward<Args>(args)...);
}
template<typename T>
void call_dtor(T& var) {
var.~T();
}
} // namespace <anonymous>
mm_message::mm_message() : next(0), type(mm_message_type::shutdown) { }
mm_message::mm_message(process_information_ptr a0, addressed_message a1)
: next(0), type(mm_message_type::outgoing_message) {
call_ctor(out_msg, std::move(a0), std::move(a1));
}
mm_message::mm_message(util::io_stream_ptr_pair a0, process_information_ptr a1)
: next(0), type(mm_message_type::add_peer) {
call_ctor(peer, std::move(a0), std::move(a1));
}
mm_message::~mm_message() {
switch (type) {
case mm_message_type::outgoing_message: {
call_dtor(out_msg);
break;
}
case mm_message_type::add_peer: {
call_dtor(peer);
break;
}
default: break;
}
}
void mailman_loop(intrusive::single_reader_queue<mm_message>& q) {
bool done = false;
util::buffer wr_buf;
// serializes outgoing messages
binary_serializer bs(&wr_buf);
// connected tcp peers
std::map<process_information, util::io_stream_ptr_pair> peers;
std::unique_ptr<mm_message> msg;
auto fetch_next = [&] { msg.reset(q.pop()); };
for (fetch_next(); !done; fetch_next()) {
switch (msg->type) {
case mm_message_type::outgoing_message: {
auto& target_peer = msg->out_msg.first;
auto& out_msg = msg->out_msg.second;
CPPA_REQUIRE(target_peer != nullptr);
auto i = peers.find(*target_peer);
if (i != peers.end()) {
bool disconnect_peer = false;
bs.reset();
wr_buf.reset();
try {
bs << out_msg;
DEBUG("--> " << to_string(out_msg));
DEBUG("outgoing message size: " << bs.size());
i->second.second->write(wr_buf.data(), wr_buf.size());
}
// something went wrong; close connection to this peer
catch (std::exception& e) {
DEBUG(to_uniform_name(typeid(e)) << ": " << e.what());
disconnect_peer = true;
}
if (disconnect_peer) {
DEBUG("peer disconnected (error during send)");
//closesocket(peer);
//post_office_close_socket(peer_fd);
peers.erase(i);
}
}
else {
DEBUG("message to an unknown peer: " << to_string(out_msg));
}
break;
}
case mm_message_type::add_peer: {
DEBUG("mailman: add_peer");
auto& iopair = msg->peer.first;
auto& pinfo = msg->peer.second;
auto i = peers.find(*pinfo);
if (i == peers.end()) {
//cout << "mailman added " << pjob.pinfo->process_id() << "@"
// << to_string(pjob.pinfo->node_id()) << endl;
peers.insert(std::make_pair(*pinfo, iopair));
}
else {
DEBUG("add_peer failed: peer already known");
}
break;
}
case mm_message_type::shutdown: {
done = true;
}
}
}
}
} } // namespace cppa::detail
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