Commit 783cd02d authored by neverlord's avatar neverlord

select()

parent 69ef1b78
...@@ -39,7 +39,6 @@ libcppa_la_SOURCES = \ ...@@ -39,7 +39,6 @@ libcppa_la_SOURCES = \
src/partial_function.cpp \ src/partial_function.cpp \
src/pattern.cpp \ src/pattern.cpp \
src/post_office.cpp \ src/post_office.cpp \
src/post_office_msg.cpp \
src/primitive_variant.cpp \ src/primitive_variant.cpp \
src/process_information.cpp \ src/process_information.cpp \
src/receive.cpp \ src/receive.cpp \
...@@ -102,6 +101,7 @@ nobase_library_include_HEADERS = \ ...@@ -102,6 +101,7 @@ nobase_library_include_HEADERS = \
cppa/detail/demangle.hpp \ cppa/detail/demangle.hpp \
cppa/detail/disablable_delete.hpp \ cppa/detail/disablable_delete.hpp \
cppa/detail/empty_tuple.hpp \ cppa/detail/empty_tuple.hpp \
cppa/detail/filter_result.hpp \
cppa/detail/get_behavior.hpp \ cppa/detail/get_behavior.hpp \
cppa/detail/group_manager.hpp \ cppa/detail/group_manager.hpp \
cppa/detail/implicit_conversions.hpp \ cppa/detail/implicit_conversions.hpp \
...@@ -112,12 +112,12 @@ nobase_library_include_HEADERS = \ ...@@ -112,12 +112,12 @@ nobase_library_include_HEADERS = \
cppa/detail/matches.hpp \ cppa/detail/matches.hpp \
cppa/detail/mock_scheduler.hpp \ cppa/detail/mock_scheduler.hpp \
cppa/detail/native_socket.hpp \ cppa/detail/native_socket.hpp \
cppa/detail/nestable_receive_actor.hpp \
cppa/detail/network_manager.hpp \ cppa/detail/network_manager.hpp \
cppa/detail/object_array.hpp \ cppa/detail/object_array.hpp \
cppa/detail/object_impl.hpp \ cppa/detail/object_impl.hpp \
cppa/detail/pair_member.hpp \ cppa/detail/pair_member.hpp \
cppa/detail/post_office.hpp \ cppa/detail/post_office.hpp \
cppa/detail/post_office_msg.hpp \
cppa/detail/primitive_member.hpp \ cppa/detail/primitive_member.hpp \
cppa/detail/projection.hpp \ cppa/detail/projection.hpp \
cppa/detail/pseudo_tuple.hpp \ cppa/detail/pseudo_tuple.hpp \
......
...@@ -169,8 +169,6 @@ src/actor_registry.cpp ...@@ -169,8 +169,6 @@ src/actor_registry.cpp
cppa/detail/uniform_type_info_map.hpp cppa/detail/uniform_type_info_map.hpp
cppa/detail/network_manager.hpp cppa/detail/network_manager.hpp
src/network_manager.cpp src/network_manager.cpp
cppa/detail/post_office_msg.hpp
src/post_office_msg.cpp
cppa/detail/group_manager.hpp cppa/detail/group_manager.hpp
src/group_manager.cpp src/group_manager.cpp
cppa/detail/empty_tuple.hpp cppa/detail/empty_tuple.hpp
......
...@@ -31,8 +31,7 @@ ...@@ -31,8 +31,7 @@
#ifndef NETWORK_MANAGER_HPP #ifndef NETWORK_MANAGER_HPP
#define NETWORK_MANAGER_HPP #define NETWORK_MANAGER_HPP
#include "cppa/detail/mailman.hpp" #include "cppa/detail/post_office.hpp"
#include "cppa/detail/post_office_msg.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -47,6 +46,8 @@ class network_manager ...@@ -47,6 +46,8 @@ class network_manager
virtual void stop() = 0; virtual void stop() = 0;
virtual void send_to_post_office(po_message const& msg) = 0;
virtual void send_to_post_office(any_tuple msg) = 0; virtual void send_to_post_office(any_tuple msg) = 0;
virtual void send_to_mailman(any_tuple msg) = 0; virtual void send_to_mailman(any_tuple msg) = 0;
......
...@@ -33,12 +33,20 @@ ...@@ -33,12 +33,20 @@
#include <memory> #include <memory>
#include "cppa/atom.hpp"
#include "cppa/actor_proxy.hpp" #include "cppa/actor_proxy.hpp"
#include "cppa/detail/native_socket.hpp" #include "cppa/detail/native_socket.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
void post_office_loop(); struct po_message
{
atom_value flag;
native_socket_type fd;
actor_id aid;
};
void post_office_loop(int input_fd);
void post_office_add_peer(native_socket_type peer_socket, void post_office_add_peer(native_socket_type peer_socket,
process_information_ptr const& peer_ptr); process_information_ptr const& peer_ptr);
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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
{
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,
process_information_ptr const& peer_ptr,
actor_proxy_ptr const& 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, actor_ptr const& whom);
};
struct proxy_exited
{
actor_proxy_ptr proxy_ptr;
inline proxy_exited(actor_proxy_ptr const& who) : proxy_ptr(who) { }
};
inline post_office_msg() : next(nullptr), m_type(invalid_type) { }
post_office_msg(native_socket_type arg0,
process_information_ptr const& arg1,
actor_proxy_ptr const& arg2,
std::unique_ptr<attachable>&& arg3);
post_office_msg(native_socket_type arg0, actor_ptr const& arg1);
post_office_msg(actor_proxy_ptr const& 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();
post_office_msg* next;
private:
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
...@@ -86,14 +86,11 @@ actor_proxy_ptr actor_proxy_cache::get(key_tuple const& key) ...@@ -86,14 +86,11 @@ actor_proxy_ptr actor_proxy_cache::get(key_tuple const& key)
} }
m_entries.insert(std::make_pair(key, result)); m_entries.insert(std::make_pair(key, result));
} }
auto msg = make_any_tuple(atom("ADD_PROXY"), result);
singleton_manager::get_network_manager()->send_to_post_office(std::move(msg));
result->enqueue(nullptr, make_any_tuple(atom("MONITOR")));
result->attach_functor([result](std::uint32_t) result->attach_functor([result](std::uint32_t)
{ {
auto msg = make_any_tuple(atom("RM_PROXY"), result); get_actor_proxy_cache().erase(result);
singleton_manager::get_network_manager()->send_to_post_office(std::move(msg));
}); });
result->enqueue(nullptr, make_any_tuple(atom("MONITOR")));
return result; return result;
} }
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "cppa/detail/mailman.hpp" #include "cppa/detail/mailman.hpp"
#include "cppa/detail/post_office.hpp" #include "cppa/detail/post_office.hpp"
#include "cppa/detail/mock_scheduler.hpp" #include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/post_office_msg.hpp"
#include "cppa/detail/network_manager.hpp" #include "cppa/detail/network_manager.hpp"
#include "cppa/detail/converted_thread_context.hpp" #include "cppa/detail/converted_thread_context.hpp"
...@@ -59,10 +58,17 @@ struct network_manager_impl : network_manager ...@@ -59,10 +58,17 @@ struct network_manager_impl : network_manager
local_actor_ptr m_post_office; local_actor_ptr m_post_office;
thread m_post_office_thread; thread m_post_office_thread;
int pipe_fd[2];
void start() // override void start() // override
{ {
if (pipe(pipe_fd) != 0)
{
CPPA_CRITICAL("cannot create pipe");
}
m_post_office.reset(new converted_thread_context); m_post_office.reset(new converted_thread_context);
m_post_office_thread = mock_scheduler::spawn_hidden_impl(post_office_loop, m_post_office); m_post_office_thread = mock_scheduler::spawn_hidden_impl(std::bind(post_office_loop, pipe_fd[0]), m_post_office);
m_mailman.reset(new converted_thread_context); m_mailman.reset(new converted_thread_context);
m_mailman_thread = mock_scheduler::spawn_hidden_impl(mailman_loop, m_mailman); m_mailman_thread = mock_scheduler::spawn_hidden_impl(mailman_loop, m_mailman);
...@@ -74,6 +80,16 @@ struct network_manager_impl : network_manager ...@@ -74,6 +80,16 @@ struct network_manager_impl : network_manager
m_mailman->enqueue(nullptr, make_any_tuple(atom("DONE"))); m_mailman->enqueue(nullptr, make_any_tuple(atom("DONE")));
m_post_office_thread.join(); m_post_office_thread.join();
m_mailman_thread.join(); m_mailman_thread.join();
close(pipe_fd[0]);
close(pipe_fd[0]);
}
void send_to_post_office(po_message const& msg)
{
if (write(pipe_fd[1], &msg, sizeof(po_message)) != sizeof(po_message))
{
CPPA_CRITICAL("cannot write to pipe");
}
} }
void send_to_post_office(any_tuple msg) void send_to_post_office(any_tuple msg)
......
This diff is collapsed.
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 "cppa/detail/post_office_msg.hpp"
namespace cppa { namespace detail {
post_office_msg::add_peer::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)
: sockfd(peer_socket)
, peer(peer_ptr)
, first_peer_actor(peer_actor_ptr)
, attachable_ptr(std::move(peer_observer))
{
}
post_office_msg::add_server_socket::add_server_socket(native_socket_type ssockfd,
const actor_ptr& whom)
: server_sockfd(ssockfd)
, published_actor(whom)
{
}
post_office_msg::post_office_msg(native_socket_type arg0,
const process_information_ptr& arg1,
const actor_proxy_ptr& arg2,
std::unique_ptr<attachable>&& arg3)
: next(nullptr)
, m_type(add_peer_type)
{
new (&m_add_peer_msg) add_peer(arg0, arg1, arg2, std::move(arg3));
}
post_office_msg::post_office_msg(native_socket_type arg0, const actor_ptr& arg1)
: next(nullptr)
, m_type(add_server_socket_type)
{
new (&m_add_server_socket) add_server_socket(arg0, arg1);
}
post_office_msg::post_office_msg(const actor_proxy_ptr& proxy_ptr)
: next(nullptr)
, m_type(proxy_exited_type)
{
new (&m_proxy_exited) proxy_exited(proxy_ptr);
}
post_office_msg::~post_office_msg()
{
switch (m_type)
{
case add_peer_type:
{
m_add_peer_msg.~add_peer();
break;
}
case add_server_socket_type:
{
m_add_server_socket.~add_server_socket();
break;
}
case proxy_exited_type:
{
m_proxy_exited.~proxy_exited();
break;
}
default: break;
}
}
} } // namespace cppa::detail
...@@ -129,6 +129,14 @@ void publish(actor_ptr& whom, std::uint16_t port) ...@@ -129,6 +129,14 @@ void publish(actor_ptr& whom, std::uint16_t port)
serv_addr.sin_family = AF_INET; serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port); serv_addr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
{
throw bind_failure(errno);
}
if (listen(sockfd, 10) != 0)
{
throw network_error("listen() failed");
}
int flags = fcntl(sockfd, F_GETFL, 0); int flags = fcntl(sockfd, F_GETFL, 0);
if (flags == -1) if (flags == -1)
{ {
...@@ -140,14 +148,6 @@ void publish(actor_ptr& whom, std::uint16_t port) ...@@ -140,14 +148,6 @@ void publish(actor_ptr& whom, std::uint16_t port)
} }
flags = 1; flags = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int)); setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int));
if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
{
throw bind_failure(errno);
}
if (listen(sockfd, 10) != 0)
{
throw network_error("listen() failed");
}
// ok, no exceptions // ok, no exceptions
sguard.release(); sguard.release();
detail::post_office_publish(sockfd, whom); detail::post_office_publish(sockfd, whom);
...@@ -195,6 +195,17 @@ actor_ptr remote_actor(const char* host, std::uint16_t port) ...@@ -195,6 +195,17 @@ actor_ptr remote_actor(const char* host, std::uint16_t port)
read_from_socket(sockfd, &remote_actor_id, sizeof(remote_actor_id)); read_from_socket(sockfd, &remote_actor_id, sizeof(remote_actor_id));
read_from_socket(sockfd, &peer_pid, sizeof(std::uint32_t)); read_from_socket(sockfd, &peer_pid, sizeof(std::uint32_t));
read_from_socket(sockfd, peer_node_id.data(), peer_node_id.size()); read_from_socket(sockfd, peer_node_id.data(), peer_node_id.size());
flags = fcntl(sockfd, F_GETFL, 0);
if (flags == -1)
{
throw network_error("unable to get socket flags");
}
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
throw network_error("unable to set socket to nonblock");
}
auto peer_pinf = new process_information(peer_pid, peer_node_id); auto peer_pinf = new process_information(peer_pid, peer_node_id);
process_information_ptr pinfptr(peer_pinf); process_information_ptr pinfptr(peer_pinf);
auto key = std::make_tuple(remote_actor_id, pinfptr->process_id(), pinfptr->node_id()); auto key = std::make_tuple(remote_actor_id, pinfptr->process_id(), pinfptr->node_id());
......
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