Commit 783cd02d authored by neverlord's avatar neverlord

select()

parent 69ef1b78
......@@ -39,7 +39,6 @@ libcppa_la_SOURCES = \
src/partial_function.cpp \
src/pattern.cpp \
src/post_office.cpp \
src/post_office_msg.cpp \
src/primitive_variant.cpp \
src/process_information.cpp \
src/receive.cpp \
......@@ -102,6 +101,7 @@ nobase_library_include_HEADERS = \
cppa/detail/demangle.hpp \
cppa/detail/disablable_delete.hpp \
cppa/detail/empty_tuple.hpp \
cppa/detail/filter_result.hpp \
cppa/detail/get_behavior.hpp \
cppa/detail/group_manager.hpp \
cppa/detail/implicit_conversions.hpp \
......@@ -112,12 +112,12 @@ nobase_library_include_HEADERS = \
cppa/detail/matches.hpp \
cppa/detail/mock_scheduler.hpp \
cppa/detail/native_socket.hpp \
cppa/detail/nestable_receive_actor.hpp \
cppa/detail/network_manager.hpp \
cppa/detail/object_array.hpp \
cppa/detail/object_impl.hpp \
cppa/detail/pair_member.hpp \
cppa/detail/post_office.hpp \
cppa/detail/post_office_msg.hpp \
cppa/detail/primitive_member.hpp \
cppa/detail/projection.hpp \
cppa/detail/pseudo_tuple.hpp \
......
......@@ -169,8 +169,6 @@ src/actor_registry.cpp
cppa/detail/uniform_type_info_map.hpp
cppa/detail/network_manager.hpp
src/network_manager.cpp
cppa/detail/post_office_msg.hpp
src/post_office_msg.cpp
cppa/detail/group_manager.hpp
src/group_manager.cpp
cppa/detail/empty_tuple.hpp
......
......@@ -31,8 +31,7 @@
#ifndef NETWORK_MANAGER_HPP
#define NETWORK_MANAGER_HPP
#include "cppa/detail/mailman.hpp"
#include "cppa/detail/post_office_msg.hpp"
#include "cppa/detail/post_office.hpp"
namespace cppa { namespace detail {
......@@ -47,6 +46,8 @@ class network_manager
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_mailman(any_tuple msg) = 0;
......
......@@ -33,12 +33,20 @@
#include <memory>
#include "cppa/atom.hpp"
#include "cppa/actor_proxy.hpp"
#include "cppa/detail/native_socket.hpp"
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,
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)
}
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)
{
auto msg = make_any_tuple(atom("RM_PROXY"), result);
singleton_manager::get_network_manager()->send_to_post_office(std::move(msg));
get_actor_proxy_cache().erase(result);
});
result->enqueue(nullptr, make_any_tuple(atom("MONITOR")));
return result;
}
......
......@@ -41,7 +41,6 @@
#include "cppa/detail/mailman.hpp"
#include "cppa/detail/post_office.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/post_office_msg.hpp"
#include "cppa/detail/network_manager.hpp"
#include "cppa/detail/converted_thread_context.hpp"
......@@ -59,10 +58,17 @@ struct network_manager_impl : network_manager
local_actor_ptr m_post_office;
thread m_post_office_thread;
int pipe_fd[2];
void start() // override
{
if (pipe(pipe_fd) != 0)
{
CPPA_CRITICAL("cannot create pipe");
}
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_thread = mock_scheduler::spawn_hidden_impl(mailman_loop, m_mailman);
......@@ -74,6 +80,16 @@ struct network_manager_impl : network_manager
m_mailman->enqueue(nullptr, make_any_tuple(atom("DONE")));
m_post_office_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)
......
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)
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
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);
if (flags == -1)
{
......@@ -140,14 +148,6 @@ void publish(actor_ptr& whom, std::uint16_t port)
}
flags = 1;
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
sguard.release();
detail::post_office_publish(sockfd, whom);
......@@ -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, &peer_pid, sizeof(std::uint32_t));
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);
process_information_ptr pinfptr(peer_pinf);
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