Commit 91946b53 authored by Dominik Charousset's avatar Dominik Charousset

Re-organize BASP header + documentation update

The BASP header has been re-organized for better readability and in advance
of future extensions. This is a breaking change!
parent a8c30ef2
...@@ -527,7 +527,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manual/variables.tex.in" ...@@ -527,7 +527,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manual/variables.tex.in"
# check for doxygen and add custom "doc" target to Makefile # check for doxygen and add custom "doc" target to Makefile
find_package(Doxygen) find_package(Doxygen)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in" configure_file("${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in"
"${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile" "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
@ONLY) @ONLY)
add_custom_target(doc "${DOXYGEN_EXECUTABLE}" add_custom_target(doc "${DOXYGEN_EXECUTABLE}"
......
...@@ -549,7 +549,7 @@ WARN_LOGFILE = ...@@ -549,7 +549,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = @CMAKE_HOME_DIRECTORY@/libcaf_core/caf @CMAKE_HOME_DIRECTORY@/libcaf_core/caf/mixin @CMAKE_HOME_DIRECTORY@/libcaf_core/caf/policy @CMAKE_HOME_DIRECTORY@/libcaf_io/caf/io INPUT = @CMAKE_HOME_DIRECTORY@/libcaf_core/caf @CMAKE_HOME_DIRECTORY@/libcaf_core/caf/mixin @CMAKE_HOME_DIRECTORY@/libcaf_core/caf/policy @CMAKE_HOME_DIRECTORY@/libcaf_io/caf/io @CMAKE_HOME_DIRECTORY@/libcaf_io/caf/io/network
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
...@@ -626,7 +626,7 @@ EXAMPLE_RECURSIVE = YES ...@@ -626,7 +626,7 @@ EXAMPLE_RECURSIVE = YES
# directories that contain image that are included in the documentation (see # directories that contain image that are included in the documentation (see
# the \image command). # the \image command).
IMAGE_PATH = IMAGE_PATH = @CMAKE_HOME_DIRECTORY@/doc/
# The INPUT_FILTER tag can be used to specify a program that doxygen should # The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program # invoke to filter for each input file. Doxygen will invoke the filter program
......
...@@ -148,8 +148,7 @@ ...@@ -148,8 +148,7 @@
/// The {@link math_actor.cpp Math Actor Example} shows the usage /// The {@link math_actor.cpp Math Actor Example} shows the usage
/// of {@link receive_loop} and {@link caf::arg_match arg_match}. /// of {@link receive_loop} and {@link caf::arg_match arg_match}.
/// The {@link dining_philosophers.cpp Dining Philosophers Example} /// The {@link dining_philosophers.cpp Dining Philosophers Example}
/// introduces event-based actors and includes a lot of `libcaf /// introduces event-based actors covers various features of CAF.
/// features.
/// ///
/// @namespace caf /// @namespace caf
/// Root namespace of libcaf. /// Root namespace of libcaf.
...@@ -164,35 +163,38 @@ ...@@ -164,35 +163,38 @@
/// Contains policies encapsulating characteristics or algorithms. /// Contains policies encapsulating characteristics or algorithms.
/// ///
/// @namespace caf::io /// @namespace caf::io
/// Contains all network-related classes and functions. /// Contains all IO-related classes and functions.
///
/// @namespace caf::io::network
/// Contains classes and functions used for network abstraction.
/// ///
/// @namespace caf::io::basp /// @namespace caf::io::basp
/// Contains all classes and functions for the Binary Actor Sytem Protocol. /// Contains all classes and functions for the Binary Actor Sytem Protocol.
/// ///
/// @defgroup MessageHandling Message handling. /// @defgroup MessageHandling Message Handling
/// ///
/// This is the beating heart of `libcaf`. Actor programming is /// This is the beating heart of CAF, since actor programming is
/// all about message handling. /// a message oriented programming paradigm.
/// ///
/// A message in `libcaf` is a n-tuple of values (with size >= 1) /// A message in CAF is a n-tuple of values (with size >= 1).
/// You can use almost every type in a messages - as long as it is announced, /// You can use almost every type in a messages as long as it is announced,
/// i.e., known by the type system of `libcaf`. /// i.e., known by the type system of CAF.
/// ///
/// @defgroup BlockingAPI Blocking API. /// @defgroup BlockingAPI Blocking API
/// ///
/// Blocking functions to receive messages. /// Blocking functions to receive messages.
/// ///
/// The blocking API of libcaf is intended to be used for migrating /// The blocking API of CAF is intended to be used for migrating
/// previously threaded applications. When writing new code, you should use /// previously threaded applications. When writing new code, you should
/// ibcafs nonblocking become/unbecome API. /// consider the nonblocking API based on `become` and `unbecome` first.
/// ///
/// @section Send Send messages /// @section Send Sending Messages
/// ///
/// The function `send` can be used to send a message to an actor. /// The function `send` can be used to send a message to an actor.
/// The first argument is the receiver of the message followed by any number /// The first argument is the receiver of the message followed by any number
/// of values: /// of values:
/// ///
/// @code /// ~~
/// // spawn some actors /// // spawn some actors
/// auto a1 = spawn(...); /// auto a1 = spawn(...);
/// auto a2 = spawn(...); /// auto a2 = spawn(...);
...@@ -206,14 +208,14 @@ ...@@ -206,14 +208,14 @@
/// send(a1, msg); /// send(a1, msg);
/// send(a2, msg); /// send(a2, msg);
/// send(a3, msg); /// send(a3, msg);
/// @endcode /// ~~
/// ///
/// @section Receive Receive messages /// @section Receive Receive messages
/// ///
/// The function `receive` takes a `behavior` as argument. The behavior /// The function `receive` takes a `behavior` as argument. The behavior
/// is a list of { pattern >> callback } rules. /// is a list of { pattern >> callback } rules.
/// ///
/// @code /// ~~
/// receive /// receive
/// ( /// (
/// on(atom("hello"), arg_match) >> [](const std::string& msg) /// on(atom("hello"), arg_match) >> [](const std::string& msg)
...@@ -226,7 +228,7 @@ ...@@ -226,7 +228,7 @@
/// return make_message(atom("result"), i0 + i1 + i2); /// return make_message(atom("result"), i0 + i1 + i2);
/// } /// }
/// ); /// );
/// @endcode /// ~~
/// ///
/// Please read the manual for further details about pattern matching. /// Please read the manual for further details about pattern matching.
/// ///
...@@ -239,7 +241,7 @@ ...@@ -239,7 +241,7 @@
/// what operation the sender of a message wanted by receiving just two integers. /// what operation the sender of a message wanted by receiving just two integers.
/// ///
/// Example actor: /// Example actor:
/// @code /// ~~
/// void math_actor() { /// void math_actor() {
/// receive_loop ( /// receive_loop (
/// on(atom("plus"), arg_match) >> [](int a, int b) { /// on(atom("plus"), arg_match) >> [](int a, int b) {
...@@ -250,9 +252,9 @@ ...@@ -250,9 +252,9 @@
/// } /// }
/// ); /// );
/// } /// }
/// @endcode /// ~~
/// ///
/// @section ReceiveLoops Receive loops /// @section ReceiveLoops Receive Loops
/// ///
/// Previous examples using `receive` create behaviors on-the-fly. /// Previous examples using `receive` create behaviors on-the-fly.
/// This is inefficient in a loop since the argument passed to receive /// This is inefficient in a loop since the argument passed to receive
...@@ -270,7 +272,7 @@ ...@@ -270,7 +272,7 @@
/// `receive_while` creates a functor evaluating a lambda expression. /// `receive_while` creates a functor evaluating a lambda expression.
/// The loop continues until the given lambda returns `false`. A simple example: /// The loop continues until the given lambda returns `false`. A simple example:
/// ///
/// @code /// ~~
/// // receive two integers /// // receive two integers
/// vector<int> received_values; /// vector<int> received_values;
/// receive_while([&]() { return received_values.size() < 2; }) ( /// receive_while([&]() { return received_values.size() < 2; }) (
...@@ -279,23 +281,23 @@ ...@@ -279,23 +281,23 @@
/// } /// }
/// ); /// );
/// // ... /// // ...
/// @endcode /// ~~
/// ///
/// `receive_for` is a simple ranged-based loop: /// `receive_for` is a simple ranged-based loop:
/// ///
/// @code /// ~~
/// std::vector<int> vec {1, 2, 3, 4}; /// std::vector<int> vec {1, 2, 3, 4};
/// auto i = vec.begin(); /// auto i = vec.begin();
/// receive_for(i, vec.end()) ( /// receive_for(i, vec.end()) (
/// on(atom("get")) >> [&]() -> message { return {atom("result"), *i}; } /// on(atom("get")) >> [&]() -> message { return {atom("result"), *i}; }
/// ); /// );
/// @endcode /// ~~
/// ///
/// `do_receive` returns a functor providing the function `until` that /// `do_receive` returns a functor providing the function `until` that
/// takes a lambda expression. The loop continues until the given lambda /// takes a lambda expression. The loop continues until the given lambda
/// returns true. Example: /// returns true. Example:
/// ///
/// @code /// ~~
/// // receive ints until zero was received /// // receive ints until zero was received
/// vector<int> received_values; /// vector<int> received_values;
/// do_receive ( /// do_receive (
...@@ -305,29 +307,29 @@ ...@@ -305,29 +307,29 @@
/// ) /// )
/// .until([&]() { return received_values.back() == 0 }); /// .until([&]() { return received_values.back() == 0 });
/// // ... /// // ...
/// @endcode /// ~~
/// ///
/// @section FutureSend Send delayed messages /// @section FutureSend Sending Delayed Messages
/// ///
/// The function `delayed_send` provides a simple way to delay a message. /// The function `delayed_send` provides a simple way to delay a message.
/// This is particularly useful for recurring events, e.g., periodical polling. /// This is particularly useful for recurring events, e.g., periodical polling.
/// Usage example: /// Usage example:
/// ///
/// @code /// ~~
/// delayed_send(self, std::chrono::seconds(1), atom("poll")); /// delayed_send(self, std::chrono::seconds(1), poll_atom::value);
/// receive_loop ( /// receive_loop (
/// // ... /// // ...
/// on(atom("poll")) >> [] { /// [](poll_atom) {
/// // ... poll something ... /// // ... poll something ...
/// // and do it again after 1sec /// // and do it again after 1sec
/// delayed_send(self, std::chrono::seconds(1), atom("poll")); /// delayed_send(self, std::chrono::seconds(1), poll_atom::value);
/// } /// }
/// ); /// );
/// @endcode /// ~~
/// ///
/// See also the {@link dancing_kirby.cpp dancing kirby example}. /// See also the {@link dancing_kirby.cpp dancing kirby example}.
/// ///
/// @defgroup ImplicitConversion Implicit type conversions. /// @defgroup ImplicitConversion Implicit Type Conversions
/// ///
/// The message passing of `libcaf` prohibits pointers in messages because /// The message passing of `libcaf` prohibits pointers in messages because
/// it enforces network transparent messaging. /// it enforces network transparent messaging.
...@@ -337,7 +339,7 @@ ...@@ -337,7 +339,7 @@
/// It also converts unicode literals to the corresponding STL container. /// It also converts unicode literals to the corresponding STL container.
/// ///
/// A few examples: /// A few examples:
/// @code /// ~~
/// // sends an std::string containing "hello actor!" to itself /// // sends an std::string containing "hello actor!" to itself
/// send(self, "hello actor!"); /// send(self, "hello actor!");
/// ///
...@@ -355,9 +357,9 @@ ...@@ -355,9 +357,9 @@
/// // equal to: on(std::string("hello actor!")) /// // equal to: on(std::string("hello actor!"))
/// on("hello actor!") >> [] { } /// on("hello actor!") >> [] { }
/// ); /// );
/// @endcode /// ~~
/// ///
/// @defgroup ActorCreation Actor creation. /// @defgroup ActorCreation Creating Actors
// examples // examples
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
namespace caf { namespace caf {
/// @ingroup ActorCreation /// @addtogroup ActorCreation
/// @{ /// @{
/// Stores options passed to the `spawn` function family. /// Stores options passed to the `spawn` function family.
......
...@@ -12,6 +12,7 @@ set (LIBCAF_IO_SRCS ...@@ -12,6 +12,7 @@ set (LIBCAF_IO_SRCS
src/abstract_broker.cpp src/abstract_broker.cpp
src/broker.cpp src/broker.cpp
src/default_multiplexer.cpp src/default_multiplexer.cpp
src/doorman.cpp
src/max_msg_size.cpp src/max_msg_size.cpp
src/middleman.cpp src/middleman.cpp
src/hook.cpp src/hook.cpp
...@@ -22,6 +23,7 @@ set (LIBCAF_IO_SRCS ...@@ -22,6 +23,7 @@ set (LIBCAF_IO_SRCS
src/remote_group.cpp src/remote_group.cpp
src/manager.cpp src/manager.cpp
src/set_middleman.cpp src/set_middleman.cpp
src/scribe.cpp
src/stream_manager.cpp src/stream_manager.cpp
src/test_multiplexer.cpp src/test_multiplexer.cpp
src/unpublish.cpp src/unpublish.cpp
......
This diff is collapsed.
This diff is collapsed.
...@@ -32,8 +32,9 @@ ...@@ -32,8 +32,9 @@
namespace caf { namespace caf {
namespace io { namespace io {
/// A broker mediates between actor systems and other components in the network. /// Describes a dynamically typed broker.
/// @extends local_actor /// @extends abstract_broker
/// @ingroup Broker
class broker : public abstract_event_based_actor<behavior, false, class broker : public abstract_event_based_actor<behavior, false,
abstract_broker> { abstract_broker> {
public: public:
...@@ -50,7 +51,7 @@ public: ...@@ -50,7 +51,7 @@ public:
CAF_ASSERT(sptr->hdl() == hdl); CAF_ASSERT(sptr->hdl() == hdl);
return spawn_functor(nullptr, return spawn_functor(nullptr,
[sptr](broker* forked) { [sptr](broker* forked) {
sptr->set_broker(forked); sptr->set_parent(forked);
forked->scribes_.emplace(sptr->hdl(), sptr); forked->scribes_.emplace(sptr->hdl(), sptr);
}, },
fun, hdl, std::forward<Ts>(xs)...); fun, hdl, std::forward<Ts>(xs)...);
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_IO_DOORMAN_HPP
#define CAF_IO_DOORMAN_HPP
#include <cstddef>
#include "caf/message.hpp"
#include "caf/io/accept_handle.hpp"
#include "caf/io/system_messages.hpp"
#include "caf/io/network/acceptor_manager.hpp"
namespace caf {
namespace io {
/// Manages incoming connections.
/// @ingroup Broker
class doorman : public network::acceptor_manager {
public:
doorman(abstract_broker* parent, accept_handle hdl, uint16_t local_port);
~doorman();
inline accept_handle hdl() const {
return hdl_;
}
void io_failure(network::operation op) override;
// needs to be launched explicitly
virtual void launch() = 0;
uint16_t port() const {
return port_;
}
protected:
void detach_from_parent() override;
message detach_message() override;
inline new_connection_msg& accept_msg() {
return accept_msg_.get_as_mutable<new_connection_msg>(0);
}
inline const new_connection_msg& accept_msg() const {
return accept_msg_.get_as<new_connection_msg>(0);
}
accept_handle hdl_;
message accept_msg_;
uint16_t port_;
};
} // namespace io
} // namespace caf
#endif // CAF_IO_DOORMAN_HPP
...@@ -187,7 +187,7 @@ public: ...@@ -187,7 +187,7 @@ public:
"Cannot fork: new broker misses required handlers"); "Cannot fork: new broker misses required handlers");
return spawn_functor_impl<no_spawn_options, impl>( return spawn_functor_impl<no_spawn_options, impl>(
nullptr, [&sptr](abstract_broker* forked) { nullptr, [&sptr](abstract_broker* forked) {
sptr->set_broker(forked); sptr->set_parent(forked);
forked->add_scribe(sptr); forked->add_scribe(sptr);
}, },
std::move(fun), hdl, std::forward<Ts>(xs)...); std::move(fun), hdl, std::forward<Ts>(xs)...);
......
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
namespace caf { namespace caf {
namespace io { namespace io {
class basp_broker;
class abstract_broker;
class broker; class broker;
class middleman; class middleman;
class basp_broker;
class receive_policy; class receive_policy;
class abstract_broker;
namespace network { namespace network {
......
...@@ -30,6 +30,8 @@ namespace network { ...@@ -30,6 +30,8 @@ namespace network {
/// callbacks for incoming connections as well as for error handling. /// callbacks for incoming connections as well as for error handling.
class acceptor_manager : public manager { class acceptor_manager : public manager {
public: public:
acceptor_manager(abstract_broker* ptr);
~acceptor_manager(); ~acceptor_manager();
/// Called by the underlying IO device to indicate that /// Called by the underlying IO device to indicate that
......
...@@ -115,7 +115,7 @@ template <class Socket> ...@@ -115,7 +115,7 @@ template <class Socket>
connection_handle asio_multiplexer::add_tcp_scribe(abstract_broker* self, connection_handle asio_multiplexer::add_tcp_scribe(abstract_broker* self,
Socket&& sock) { Socket&& sock) {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
class impl : public abstract_broker::scribe { class impl : public scribe {
public: public:
impl(abstract_broker* ptr, Socket&& s) impl(abstract_broker* ptr, Socket&& s)
: scribe(ptr, network::conn_hdl_from_socket(s)), : scribe(ptr, network::conn_hdl_from_socket(s)),
...@@ -130,16 +130,16 @@ connection_handle asio_multiplexer::add_tcp_scribe(abstract_broker* self, ...@@ -130,16 +130,16 @@ connection_handle asio_multiplexer::add_tcp_scribe(abstract_broker* self,
launch(); launch();
} }
} }
abstract_broker::buffer_type& wr_buf() override { std::vector<char>& wr_buf() override {
return stream_.wr_buf(); return stream_.wr_buf();
} }
abstract_broker::buffer_type& rd_buf() override { std::vector<char>& rd_buf() override {
return stream_.rd_buf(); return stream_.rd_buf();
} }
void stop_reading() override { void stop_reading() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
stream_.stop_reading(); stream_.stop_reading();
disconnect(false); detach(false);
} }
void flush() override { void flush() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
...@@ -156,7 +156,7 @@ connection_handle asio_multiplexer::add_tcp_scribe(abstract_broker* self, ...@@ -156,7 +156,7 @@ connection_handle asio_multiplexer::add_tcp_scribe(abstract_broker* self,
bool launched_; bool launched_;
stream<Socket> stream_; stream<Socket> stream_;
}; };
abstract_broker::scribe_ptr ptr = make_counted<impl>(self, std::move(sock)); auto ptr = make_counted<impl>(self, std::move(sock));
self->add_scribe(ptr); self->add_scribe(ptr);
return ptr->hdl(); return ptr->hdl();
} }
...@@ -210,7 +210,7 @@ asio_multiplexer::add_tcp_doorman(abstract_broker* self, ...@@ -210,7 +210,7 @@ asio_multiplexer::add_tcp_doorman(abstract_broker* self,
default_socket_acceptor&& sock) { default_socket_acceptor&& sock) {
CAF_LOG_TRACE("sock.fd = " << sock.native_handle()); CAF_LOG_TRACE("sock.fd = " << sock.native_handle());
CAF_ASSERT(sock.native_handle() != network::invalid_native_socket); CAF_ASSERT(sock.native_handle() != network::invalid_native_socket);
class impl : public abstract_broker::doorman { class impl : public doorman {
public: public:
impl(abstract_broker* ptr, default_socket_acceptor&& s, impl(abstract_broker* ptr, default_socket_acceptor&& s,
network::asio_multiplexer& am) network::asio_multiplexer& am)
...@@ -230,7 +230,7 @@ asio_multiplexer::add_tcp_doorman(abstract_broker* self, ...@@ -230,7 +230,7 @@ asio_multiplexer::add_tcp_doorman(abstract_broker* self,
void stop_reading() override { void stop_reading() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
acceptor_.stop(); acceptor_.stop();
disconnect(false); detach(false);
} }
void launch() override { void launch() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
...@@ -240,8 +240,7 @@ asio_multiplexer::add_tcp_doorman(abstract_broker* self, ...@@ -240,8 +240,7 @@ asio_multiplexer::add_tcp_doorman(abstract_broker* self,
private: private:
network::acceptor<default_socket_acceptor> acceptor_; network::acceptor<default_socket_acceptor> acceptor_;
}; };
abstract_broker::doorman_ptr ptr auto ptr = make_counted<impl>(self, std::move(sock), *this);
= make_counted<impl>(self, std::move(sock), *this);
self->add_doorman(ptr); self->add_doorman(ptr);
return ptr->hdl(); return ptr->hdl();
} }
......
...@@ -20,9 +20,11 @@ ...@@ -20,9 +20,11 @@
#ifndef CAF_IO_NETWORK_MANAGER_HPP #ifndef CAF_IO_NETWORK_MANAGER_HPP
#define CAF_IO_NETWORK_MANAGER_HPP #define CAF_IO_NETWORK_MANAGER_HPP
#include "caf/message.hpp"
#include "caf/ref_counted.hpp" #include "caf/ref_counted.hpp"
#include "caf/intrusive_ptr.hpp" #include "caf/intrusive_ptr.hpp"
#include "caf/io/fwd.hpp"
#include "caf/io/network/operation.hpp" #include "caf/io/network/operation.hpp"
namespace caf { namespace caf {
...@@ -33,14 +35,44 @@ namespace network { ...@@ -33,14 +35,44 @@ namespace network {
/// for various IO operations. /// for various IO operations.
class manager : public ref_counted { class manager : public ref_counted {
public: public:
manager(abstract_broker* parent_ptr);
~manager(); ~manager();
/// Sets the parent for this manager.
/// @pre `parent() == nullptr`
void set_parent(abstract_broker* ptr);
/// Returns the parent broker of this manager.
inline abstract_broker* parent() {
return parent_;
}
/// Returns `true` if this manager has a parent, `false` otherwise.
inline bool detached() const {
return parent_ == nullptr;
}
/// Detach this manager from its parent and invoke `detach_message()``
/// if `invoke_detach_message == true`.
void detach(bool invoke_detach_message);
/// Causes the manager to stop read operations on its IO device. /// Causes the manager to stop read operations on its IO device.
/// Unwritten bytes are still send before the socket will be closed. /// Unwritten bytes are still send before the socket will be closed.
virtual void stop_reading() = 0; virtual void stop_reading() = 0;
/// Called by the underlying IO device to report failures. /// Called by the underlying IO device to report failures.
virtual void io_failure(operation op) = 0; virtual void io_failure(operation op) = 0;
protected:
/// Creates a message signalizing a disconnect to the parent.
virtual message detach_message() = 0;
/// Detaches this manager from its parent.
virtual void detach_from_parent() = 0;
private:
abstract_broker* parent_;
}; };
} // namespace network } // namespace network
......
...@@ -32,6 +32,8 @@ namespace network { ...@@ -32,6 +32,8 @@ namespace network {
/// for incoming data as well as for error handling. /// for incoming data as well as for error handling.
class stream_manager : public manager { class stream_manager : public manager {
public: public:
stream_manager(abstract_broker* ptr);
~stream_manager(); ~stream_manager();
/// Called by the underlying IO device whenever it received data. /// Called by the underlying IO device whenever it received data.
......
...@@ -77,7 +77,7 @@ public: ...@@ -77,7 +77,7 @@ public:
bool& stopped_reading(connection_handle hdl); bool& stopped_reading(connection_handle hdl);
abstract_broker::scribe_ptr& impl_ptr(connection_handle hdl); intrusive_ptr<scribe>& impl_ptr(connection_handle hdl);
uint16_t& port(accept_handle hdl); uint16_t& port(accept_handle hdl);
...@@ -85,7 +85,7 @@ public: ...@@ -85,7 +85,7 @@ public:
/// `false` otherwise. /// `false` otherwise.
bool& stopped_reading(accept_handle hdl); bool& stopped_reading(accept_handle hdl);
abstract_broker::doorman_ptr& impl_ptr(accept_handle hdl); intrusive_ptr<doorman>& impl_ptr(accept_handle hdl);
void add_pending_connect(accept_handle src, connection_handle hdl); void add_pending_connect(accept_handle src, connection_handle hdl);
...@@ -128,13 +128,13 @@ private: ...@@ -128,13 +128,13 @@ private:
buffer_type wr_buf; buffer_type wr_buf;
receive_policy::config recv_conf; receive_policy::config recv_conf;
bool stopped_reading = false; bool stopped_reading = false;
abstract_broker::scribe_ptr ptr; intrusive_ptr<scribe> ptr;
}; };
struct doorman_data { struct doorman_data {
uint16_t port; uint16_t port;
bool stopped_reading = false; bool stopped_reading = false;
abstract_broker::doorman_ptr ptr; intrusive_ptr<doorman> ptr;
}; };
std::mutex mx_; std::mutex mx_;
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_IO_SCRIBE_HPP
#define CAF_IO_SCRIBE_HPP
#include <vector>
#include "caf/message.hpp"
#include "caf/io/receive_policy.hpp"
#include "caf/io/system_messages.hpp"
#include "caf/io/network/stream_manager.hpp"
namespace caf {
namespace io {
/// Manages a stream.
/// @ingroup Broker
class scribe : public network::stream_manager {
public:
scribe(abstract_broker* parent, connection_handle hdl);
~scribe();
/// Implicitly starts the read loop on first call.
virtual void configure_read(receive_policy::config config) = 0;
/// Grants access to the output buffer.
virtual std::vector<char>& wr_buf() = 0;
/// Flushes the output buffer, i.e., sends the content of
/// the buffer via the network.
virtual void flush() = 0;
inline connection_handle hdl() const {
return hdl_;
}
void io_failure(network::operation op) override;
void consume(const void* data, size_t num_bytes) override;
protected:
virtual std::vector<char>& rd_buf() = 0;
inline new_data_msg& read_msg() {
return read_msg_.get_as_mutable<new_data_msg>(0);
}
inline const new_data_msg& read_msg() const {
return read_msg_.get_as<new_data_msg>(0);
}
void detach_from_parent() override;
message detach_message() override;
private:
connection_handle hdl_;
message read_msg_;
};
} // namespace io
} // namespace caf
#endif // CAF_IO_SCRIBE_HPP
...@@ -97,114 +97,6 @@ void abstract_broker::cleanup(uint32_t reason) { ...@@ -97,114 +97,6 @@ void abstract_broker::cleanup(uint32_t reason) {
deref(); // release implicit reference count from middleman deref(); // release implicit reference count from middleman
} }
void abstract_broker::servant::set_broker(abstract_broker* new_broker) {
if (! disconnected_) {
broker_ = new_broker;
}
}
abstract_broker::servant::~servant() {
CAF_LOG_TRACE("");
}
abstract_broker::servant::servant(abstract_broker* ptr) : disconnected_(false), broker_(ptr) {
// nop
}
void abstract_broker::servant::disconnect(bool invoke_disconnect_message) {
CAF_LOG_TRACE("");
if (! disconnected_) {
CAF_LOG_DEBUG("disconnect servant from broker");
disconnected_ = true;
remove_from_broker();
if (invoke_disconnect_message) {
auto msg = disconnect_message();
broker_->invoke_message(broker_->address(),invalid_message_id, msg);
}
}
}
abstract_broker::scribe::scribe(abstract_broker* ptr, connection_handle conn_hdl)
: servant(ptr),
hdl_(conn_hdl) {
std::vector<char> tmp;
read_msg_ = make_message(new_data_msg{hdl_, std::move(tmp)});
}
void abstract_broker::scribe::remove_from_broker() {
CAF_LOG_TRACE("hdl = " << hdl().id());
broker_->scribes_.erase(hdl());
}
abstract_broker::scribe::~scribe() {
CAF_LOG_TRACE("");
}
message abstract_broker::scribe::disconnect_message() {
return make_message(connection_closed_msg{hdl()});
}
void abstract_broker::scribe::consume(const void*, size_t num_bytes) {
CAF_LOG_TRACE(CAF_ARG(num_bytes));
if (disconnected_) {
// we are already disconnected from the broker while the multiplexer
// did not yet remove the socket, this can happen if an IO event causes
// the broker to call close_all() while the pollset contained
// further activities for the broker
return;
}
auto& buf = rd_buf();
CAF_ASSERT(buf.size() >= num_bytes);
// make sure size is correct, swap into message, and then call client
buf.resize(num_bytes);
read_msg().buf.swap(buf);
broker_->invoke_message(invalid_actor_addr, invalid_message_id, read_msg_);
// swap buffer back to stream and implicitly flush wr_buf()
if (broker_->exit_reason() == exit_reason::not_exited) {
read_msg().buf.swap(buf);
flush();
}
}
void abstract_broker::scribe::io_failure(network::operation op) {
CAF_LOG_TRACE("id = " << hdl().id()
<< ", " << CAF_TARG(op, static_cast<int>));
// keep compiler happy when compiling w/o logging
static_cast<void>(op);
disconnect(true);
}
abstract_broker::doorman::doorman(abstract_broker* ptr,
accept_handle acc_hdl,
uint16_t p)
: servant(ptr),
hdl_(acc_hdl),
port_(p) {
auto hdl2 = connection_handle::from_int(-1);
accept_msg_ = make_message(new_connection_msg{hdl_, hdl2});
}
abstract_broker::doorman::~doorman() {
CAF_LOG_TRACE("");
}
void abstract_broker::doorman::remove_from_broker() {
CAF_LOG_TRACE("hdl = " << hdl().id());
broker_->doormen_.erase(hdl());
}
message abstract_broker::doorman::disconnect_message() {
return make_message(acceptor_closed_msg{hdl()});
}
void abstract_broker::doorman::io_failure(network::operation op) {
CAF_LOG_TRACE("id = " << hdl().id() << ", "
<< CAF_TARG(op, static_cast<int>));
// keep compiler happy when compiling w/o logging
static_cast<void>(op);
disconnect(true);
}
abstract_broker::~abstract_broker() { abstract_broker::~abstract_broker() {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
} }
...@@ -216,7 +108,7 @@ void abstract_broker::configure_read(connection_handle hdl, ...@@ -216,7 +108,7 @@ void abstract_broker::configure_read(connection_handle hdl,
by_id(hdl).configure_read(cfg); by_id(hdl).configure_read(cfg);
} }
abstract_broker::buffer_type& abstract_broker::wr_buf(connection_handle hdl) { std::vector<char>& abstract_broker::wr_buf(connection_handle hdl) {
return by_id(hdl).wr_buf(); return by_id(hdl).wr_buf();
} }
...@@ -240,6 +132,9 @@ std::vector<connection_handle> abstract_broker::connections() const { ...@@ -240,6 +132,9 @@ std::vector<connection_handle> abstract_broker::connections() const {
return result; return result;
} }
void abstract_broker::add_scribe(const intrusive_ptr<scribe>& ptr) {
scribes_.emplace(ptr->hdl(), ptr);
}
connection_handle abstract_broker::add_tcp_scribe(const std::string& hostname, connection_handle abstract_broker::add_tcp_scribe(const std::string& hostname,
uint16_t port) { uint16_t port) {
CAF_LOG_TRACE(CAF_ARG(hostname) << ", " << CAF_ARG(port)); CAF_LOG_TRACE(CAF_ARG(hostname) << ", " << CAF_ARG(port));
...@@ -257,6 +152,12 @@ abstract_broker::add_tcp_scribe(network::native_socket fd) { ...@@ -257,6 +152,12 @@ abstract_broker::add_tcp_scribe(network::native_socket fd) {
return backend().add_tcp_scribe(this, fd); return backend().add_tcp_scribe(this, fd);
} }
void abstract_broker::add_doorman(const intrusive_ptr<doorman>& ptr) {
doormen_.emplace(ptr->hdl(), ptr);
if (is_initialized())
ptr->launch();
}
std::pair<accept_handle, uint16_t> std::pair<accept_handle, uint16_t>
abstract_broker::add_tcp_doorman(uint16_t port, const char* in, abstract_broker::add_tcp_doorman(uint16_t port, const char* in,
bool reuse_addr) { bool reuse_addr) {
...@@ -351,13 +252,13 @@ void abstract_broker::invoke_message(mailbox_element_ptr& ptr) { ...@@ -351,13 +252,13 @@ void abstract_broker::invoke_message(mailbox_element_ptr& ptr) {
} }
void abstract_broker::invoke_message(const actor_addr& sender, void abstract_broker::invoke_message(const actor_addr& sender,
message_id mid, message& msg) { message_id mid,
message& msg) {
auto ptr = mailbox_element::make(sender, mid, message{}); auto ptr = mailbox_element::make(sender, mid, message{});
ptr->msg.swap(msg); ptr->msg.swap(msg);
invoke_message(ptr); invoke_message(ptr);
if (ptr) { if (ptr)
ptr->msg.swap(msg); ptr->msg.swap(msg);
}
} }
void abstract_broker::close_all() { void abstract_broker::close_all() {
......
...@@ -23,6 +23,10 @@ namespace caf { ...@@ -23,6 +23,10 @@ namespace caf {
namespace io { namespace io {
namespace network { namespace network {
acceptor_manager::acceptor_manager(abstract_broker* ptr) : manager(ptr) {
// nop
}
acceptor_manager::~acceptor_manager() { acceptor_manager::~acceptor_manager() {
// nop // nop
} }
......
This diff is collapsed.
...@@ -83,9 +83,9 @@ actor_proxy_ptr basp_broker_state::make_proxy(const node_id& nid, ...@@ -83,9 +83,9 @@ actor_proxy_ptr basp_broker_state::make_proxy(const node_id& nid,
}); });
// tell remote side we are monitoring this actor now // tell remote side we are monitoring this actor now
instance.write(self->wr_buf(this_context->hdl), instance.write(self->wr_buf(this_context->hdl),
basp::message_type::announce_proxy_instance, nullptr, 0,
this_node(), nid, this_node(), nid,
invalid_actor_id, aid, invalid_actor_id, aid);
nullptr, basp::announce_proxy_instance, 0);
instance.tbl().flush(*path); instance.tbl().flush(*path);
self->parent().notify<hook::new_remote_actor>(res->address()); self->parent().notify<hook::new_remote_actor>(res->address());
return res; return res;
......
...@@ -733,7 +733,7 @@ void default_multiplexer::dispatch_runnable(runnable_ptr ptr) { ...@@ -733,7 +733,7 @@ void default_multiplexer::dispatch_runnable(runnable_ptr ptr) {
connection_handle default_multiplexer::add_tcp_scribe(abstract_broker* self, connection_handle default_multiplexer::add_tcp_scribe(abstract_broker* self,
default_socket&& sock) { default_socket&& sock) {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
class impl : public abstract_broker::scribe { class impl : public scribe {
public: public:
impl(abstract_broker* ptr, default_socket&& s) impl(abstract_broker* ptr, default_socket&& s)
: scribe(ptr, network::conn_hdl_from_socket(s)), : scribe(ptr, network::conn_hdl_from_socket(s)),
...@@ -746,16 +746,16 @@ connection_handle default_multiplexer::add_tcp_scribe(abstract_broker* self, ...@@ -746,16 +746,16 @@ connection_handle default_multiplexer::add_tcp_scribe(abstract_broker* self,
stream_.configure_read(config); stream_.configure_read(config);
if (! launched_) launch(); if (! launched_) launch();
} }
abstract_broker::buffer_type& wr_buf() override { std::vector<char>& wr_buf() override {
return stream_.wr_buf(); return stream_.wr_buf();
} }
abstract_broker::buffer_type& rd_buf() override { std::vector<char>& rd_buf() override {
return stream_.rd_buf(); return stream_.rd_buf();
} }
void stop_reading() override { void stop_reading() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
stream_.stop_reading(); stream_.stop_reading();
disconnect(false); detach(false);
} }
void flush() override { void flush() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
...@@ -771,7 +771,7 @@ connection_handle default_multiplexer::add_tcp_scribe(abstract_broker* self, ...@@ -771,7 +771,7 @@ connection_handle default_multiplexer::add_tcp_scribe(abstract_broker* self,
bool launched_; bool launched_;
stream<default_socket> stream_; stream<default_socket> stream_;
}; };
abstract_broker::scribe_ptr ptr = make_counted<impl>(self, std::move(sock)); auto ptr = make_counted<impl>(self, std::move(sock));
self->add_scribe(ptr); self->add_scribe(ptr);
return ptr->hdl(); return ptr->hdl();
} }
...@@ -781,7 +781,7 @@ default_multiplexer::add_tcp_doorman(abstract_broker* self, ...@@ -781,7 +781,7 @@ default_multiplexer::add_tcp_doorman(abstract_broker* self,
default_socket_acceptor&& sock) { default_socket_acceptor&& sock) {
CAF_LOG_TRACE("sock.fd = " << sock.fd()); CAF_LOG_TRACE("sock.fd = " << sock.fd());
CAF_ASSERT(sock.fd() != network::invalid_native_socket); CAF_ASSERT(sock.fd() != network::invalid_native_socket);
class impl : public abstract_broker::doorman { class impl : public doorman {
public: public:
impl(abstract_broker* ptr, default_socket_acceptor&& s) impl(abstract_broker* ptr, default_socket_acceptor&& s)
: doorman(ptr, network::accept_hdl_from_socket(s), port_of_fd(s.fd())), : doorman(ptr, network::accept_hdl_from_socket(s), port_of_fd(s.fd())),
...@@ -799,7 +799,7 @@ default_multiplexer::add_tcp_doorman(abstract_broker* self, ...@@ -799,7 +799,7 @@ default_multiplexer::add_tcp_doorman(abstract_broker* self,
void stop_reading() override { void stop_reading() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
acceptor_.stop_reading(); acceptor_.stop_reading();
disconnect(false); detach(false);
} }
void launch() override { void launch() override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
...@@ -808,7 +808,7 @@ default_multiplexer::add_tcp_doorman(abstract_broker* self, ...@@ -808,7 +808,7 @@ default_multiplexer::add_tcp_doorman(abstract_broker* self,
private: private:
network::acceptor<default_socket_acceptor> acceptor_; network::acceptor<default_socket_acceptor> acceptor_;
}; };
abstract_broker::doorman_ptr ptr = make_counted<impl>(self, std::move(sock)); auto ptr = make_counted<impl>(self, std::move(sock));
self->add_doorman(ptr); self->add_doorman(ptr);
return ptr->hdl(); return ptr->hdl();
} }
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/io/doorman.hpp"
#include "caf/detail/logging.hpp"
#include "caf/io/abstract_broker.hpp"
namespace caf {
namespace io {
doorman::doorman(abstract_broker* ptr, accept_handle acc_hdl, uint16_t p)
: network::acceptor_manager(ptr),
hdl_(acc_hdl),
accept_msg_(make_message(new_connection_msg{hdl_, connection_handle{}})),
port_(p) {
// nop
}
doorman::~doorman() {
// nop
}
void doorman::detach_from_parent() {
CAF_LOG_TRACE("hdl = " << hdl().id());
parent()->doormen_.erase(hdl());
}
message doorman::detach_message() {
return make_message(acceptor_closed_msg{hdl()});
}
void doorman::io_failure(network::operation op) {
CAF_LOG_TRACE("id = " << hdl().id() << ", "
<< CAF_TARG(op, static_cast<int>));
// keep compiler happy when compiling w/o logging
static_cast<void>(op);
detach(true);
}
} // namespace io
} // namespace caf
...@@ -19,14 +19,40 @@ ...@@ -19,14 +19,40 @@
#include "caf/io/network/manager.hpp" #include "caf/io/network/manager.hpp"
#include "caf/detail/logging.hpp"
#include "caf/io/abstract_broker.hpp"
namespace caf { namespace caf {
namespace io { namespace io {
namespace network { namespace network {
manager::manager(abstract_broker* ptr) : parent_(ptr) {
// nop
}
manager::~manager() { manager::~manager() {
// nop // nop
} }
void manager::set_parent(abstract_broker* ptr) {
if (! detached())
parent_ = ptr;
}
void manager::detach(bool invoke_disconnect_message) {
CAF_LOG_TRACE("");
if (! detached()) {
CAF_LOG_DEBUG("disconnect servant from broker");
detach_from_parent();
if (invoke_disconnect_message) {
auto msg = detach_message();
parent_->invoke_message(parent_->address(),invalid_message_id, msg);
}
parent_ = nullptr;
}
}
} // namespace network } // namespace network
} // namespace io } // namespace io
} // namespace caf } // namespace caf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/io/scribe.hpp"
#include "caf/detail/logging.hpp"
#include "caf/io/abstract_broker.hpp"
namespace caf {
namespace io {
scribe::scribe(abstract_broker* ptr, connection_handle conn_hdl)
: network::stream_manager(ptr),
hdl_(conn_hdl) {
std::vector<char> tmp;
read_msg_ = make_message(new_data_msg{hdl_, std::move(tmp)});
}
void scribe::detach_from_parent() {
CAF_LOG_TRACE("hdl = " << hdl().id());
parent()->scribes_.erase(hdl());
}
scribe::~scribe() {
CAF_LOG_TRACE("");
}
message scribe::detach_message() {
return make_message(connection_closed_msg{hdl()});
}
void scribe::consume(const void*, size_t num_bytes) {
CAF_LOG_TRACE(CAF_ARG(num_bytes));
if (detached()) {
// we are already disconnected from the broker while the multiplexer
// did not yet remove the socket, this can happen if an IO event causes
// the broker to call close_all() while the pollset contained
// further activities for the broker
return;
}
auto& buf = rd_buf();
CAF_ASSERT(buf.size() >= num_bytes);
// make sure size is correct, swap into message, and then call client
buf.resize(num_bytes);
read_msg().buf.swap(buf);
parent()->invoke_message(invalid_actor_addr, invalid_message_id, read_msg_);
// swap buffer back to stream and implicitly flush wr_buf()
read_msg().buf.swap(buf);
flush();
}
void scribe::io_failure(network::operation op) {
CAF_LOG_TRACE("id = " << hdl().id()
<< ", " << CAF_TARG(op, static_cast<int>));
// keep compiler happy when compiling w/o logging
static_cast<void>(op);
detach(true);
}
} // namespace io
} // namespace caf
...@@ -23,6 +23,10 @@ namespace caf { ...@@ -23,6 +23,10 @@ namespace caf {
namespace io { namespace io {
namespace network { namespace network {
stream_manager::stream_manager(abstract_broker* ptr) : manager(ptr) {
// nop
}
stream_manager::~stream_manager() { stream_manager::~stream_manager() {
// nop // nop
} }
......
...@@ -40,32 +40,32 @@ connection_handle test_multiplexer::new_tcp_scribe(const std::string& host, ...@@ -40,32 +40,32 @@ connection_handle test_multiplexer::new_tcp_scribe(const std::string& host,
void test_multiplexer::assign_tcp_scribe(abstract_broker* ptr, void test_multiplexer::assign_tcp_scribe(abstract_broker* ptr,
connection_handle hdl) { connection_handle hdl) {
class impl : public abstract_broker::scribe { class impl : public scribe {
public: public:
impl(abstract_broker* self, connection_handle ch, test_multiplexer* mpx) impl(abstract_broker* self, connection_handle ch, test_multiplexer* mpx)
: abstract_broker::scribe(self, ch), : scribe(self, ch),
mpx_(mpx) { mpx_(mpx) {
// nop // nop
} }
void configure_read(receive_policy::config config) { void configure_read(receive_policy::config config) override {
mpx_->read_config(hdl()) = config; mpx_->read_config(hdl()) = config;
} }
abstract_broker::buffer_type& wr_buf() { std::vector<char>& wr_buf() override {
return mpx_->output_buffer(hdl()); return mpx_->output_buffer(hdl());
} }
abstract_broker::buffer_type& rd_buf() { std::vector<char>& rd_buf() override {
return mpx_->input_buffer(hdl()); return mpx_->input_buffer(hdl());
} }
void stop_reading() { void stop_reading() override {
mpx_->stopped_reading(hdl()) = true; mpx_->stopped_reading(hdl()) = true;
disconnect(false); detach(false);
} }
void flush() { void flush() override {
// nop // nop
} }
...@@ -106,7 +106,7 @@ test_multiplexer::new_tcp_doorman(uint16_t port, const char*, bool) { ...@@ -106,7 +106,7 @@ test_multiplexer::new_tcp_doorman(uint16_t port, const char*, bool) {
void test_multiplexer::assign_tcp_doorman(abstract_broker* ptr, void test_multiplexer::assign_tcp_doorman(abstract_broker* ptr,
accept_handle hdl) { accept_handle hdl) {
class impl : public abstract_broker::doorman { class impl : public doorman {
public: public:
impl(abstract_broker* self, accept_handle ah, test_multiplexer* mpx) impl(abstract_broker* self, accept_handle ah, test_multiplexer* mpx)
: doorman(self, ah, mpx->port(ah)), : doorman(self, ah, mpx->port(ah)),
...@@ -127,7 +127,7 @@ void test_multiplexer::assign_tcp_doorman(abstract_broker* ptr, ...@@ -127,7 +127,7 @@ void test_multiplexer::assign_tcp_doorman(abstract_broker* ptr,
void stop_reading() { void stop_reading() {
mpx_->stopped_reading(hdl()) = true; mpx_->stopped_reading(hdl()) = true;
disconnect(false); detach(false);
} }
void launch() { void launch() {
...@@ -204,7 +204,7 @@ bool& test_multiplexer::stopped_reading(connection_handle hdl) { ...@@ -204,7 +204,7 @@ bool& test_multiplexer::stopped_reading(connection_handle hdl) {
return scribe_data_[hdl].stopped_reading; return scribe_data_[hdl].stopped_reading;
} }
abstract_broker::scribe_ptr& test_multiplexer::impl_ptr(connection_handle hdl) { intrusive_ptr<scribe>& test_multiplexer::impl_ptr(connection_handle hdl) {
return scribe_data_[hdl].ptr; return scribe_data_[hdl].ptr;
} }
...@@ -216,7 +216,7 @@ bool& test_multiplexer::stopped_reading(accept_handle hdl) { ...@@ -216,7 +216,7 @@ bool& test_multiplexer::stopped_reading(accept_handle hdl) {
return doorman_data_[hdl].stopped_reading; return doorman_data_[hdl].stopped_reading;
} }
abstract_broker::doorman_ptr& test_multiplexer::impl_ptr(accept_handle hdl) { intrusive_ptr<doorman>& test_multiplexer::impl_ptr(accept_handle hdl) {
return doorman_data_[hdl].ptr; return doorman_data_[hdl].ptr;
} }
......
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