Commit 12d04083 authored by neverlord's avatar neverlord

maintenance

parent 30e1e116
...@@ -152,6 +152,8 @@ nobase_library_include_HEADERS = \ ...@@ -152,6 +152,8 @@ nobase_library_include_HEADERS = \
cppa/get.hpp \ cppa/get.hpp \
cppa/group.hpp \ cppa/group.hpp \
cppa/guard_expr.hpp \ cppa/guard_expr.hpp \
cppa/intrusive/bidirectional_iterator.hpp \
cppa/intrusive/doubly_linked_list.hpp \
cppa/intrusive/forward_iterator.hpp \ cppa/intrusive/forward_iterator.hpp \
cppa/intrusive/single_reader_queue.hpp \ cppa/intrusive/single_reader_queue.hpp \
cppa/intrusive/singly_linked_list.hpp \ cppa/intrusive/singly_linked_list.hpp \
......
...@@ -266,3 +266,5 @@ cppa/detail/value_guard.hpp ...@@ -266,3 +266,5 @@ cppa/detail/value_guard.hpp
cppa/detail/tuple_iterator.hpp cppa/detail/tuple_iterator.hpp
cppa/match_expr.hpp cppa/match_expr.hpp
cppa/detail/pseudo_tuple.hpp cppa/detail/pseudo_tuple.hpp
cppa/intrusive/doubly_linked_list.hpp
cppa/intrusive/bidirectional_iterator.hpp
...@@ -65,12 +65,13 @@ class abstract_actor : public Base ...@@ -65,12 +65,13 @@ class abstract_actor : public Base
struct queue_node struct queue_node
{ {
queue_node* next; // intrusive next pointer queue_node* next; // intrusive next pointer
queue_node* prev; // intrusive previous pointer
bool marked; // denotes if this node is currently processed bool marked; // denotes if this node is currently processed
actor_ptr sender; actor_ptr sender;
any_tuple msg; any_tuple msg;
queue_node() : next(nullptr), marked(false) { } queue_node() : next(nullptr), prev(nullptr), marked(false) { }
queue_node(actor* from, any_tuple content) queue_node(actor* from, any_tuple content)
: next(nullptr), marked(false), sender(from), msg(std::move(content)) : next(nullptr), prev(nullptr), marked(false), sender(from), msg(std::move(content))
{ {
} }
}; };
......
...@@ -67,9 +67,6 @@ struct mailman_add_peer ...@@ -67,9 +67,6 @@ struct mailman_add_peer
class mailman_job class mailman_job
{ {
friend class intrusive::singly_linked_list<mailman_job>;
friend class intrusive::single_reader_queue<mailman_job>;
public: public:
enum job_type enum job_type
...@@ -80,7 +77,7 @@ class mailman_job ...@@ -80,7 +77,7 @@ class mailman_job
kill_type kill_type
}; };
inline mailman_job() : next(nullptr), m_type(invalid_type) { } inline mailman_job() : next(nullptr), prev(nullptr), m_type(invalid_type) { }
mailman_job(process_information_ptr piptr, mailman_job(process_information_ptr piptr,
actor_ptr const& from, actor_ptr const& from,
...@@ -123,9 +120,11 @@ class mailman_job ...@@ -123,9 +120,11 @@ class mailman_job
return m_type == kill_type; return m_type == kill_type;
} }
mailman_job* next;
mailman_job* prev;
private: private:
mailman_job* next;
job_type m_type; job_type m_type;
// unrestricted union // unrestricted union
union union
......
...@@ -43,9 +43,6 @@ namespace cppa { namespace detail { ...@@ -43,9 +43,6 @@ namespace cppa { namespace detail {
class post_office_msg class post_office_msg
{ {
friend class intrusive::singly_linked_list<post_office_msg>;
friend class intrusive::single_reader_queue<post_office_msg>;
public: public:
enum msg_type enum msg_type
...@@ -87,7 +84,7 @@ class post_office_msg ...@@ -87,7 +84,7 @@ class post_office_msg
inline proxy_exited(actor_proxy_ptr const& who) : proxy_ptr(who) { } inline proxy_exited(actor_proxy_ptr const& who) : proxy_ptr(who) { }
}; };
inline post_office_msg() : next(nullptr), m_type(invalid_type) { } inline post_office_msg() : next(0), prev(0), m_type(invalid_type) { }
post_office_msg(native_socket_type arg0, post_office_msg(native_socket_type arg0,
process_information_ptr const& arg1, process_information_ptr const& arg1,
...@@ -130,9 +127,11 @@ class post_office_msg ...@@ -130,9 +127,11 @@ class post_office_msg
~post_office_msg(); ~post_office_msg();
private:
post_office_msg* next; post_office_msg* next;
post_office_msg* prev;
private:
msg_type m_type; msg_type m_type;
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 BIDIRECTIONAL_ITERATOR_HPP
#define BIDIRECTIONAL_ITERATOR_HPP
#include <iterator>
namespace cppa { namespace intrusive {
/**
* @brief A forward iterator for intrusive lists.
*/
template<class T>
class bidirectional_iterator
{
public:
typedef T value_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
inline bidirectional_iterator(pointer ptr = nullptr) : m_ptr(ptr) { }
bidirectional_iterator(bidirectional_iterator const&) = default;
bidirectional_iterator& operator=(bidirectional_iterator const&) = default;
inline bidirectional_iterator& operator++()
{
m_ptr = m_ptr->next;
return *this;
}
inline bidirectional_iterator operator++(int)
{
bidirectional_iterator tmp{*this};
m_ptr = m_ptr->next;
return tmp;
}
inline bidirectional_iterator& operator--()
{
m_ptr = m_ptr->prev;
return *this;
}
inline bidirectional_iterator operator--(int)
{
bidirectional_iterator tmp{*this};
m_ptr = m_ptr->prev;
return tmp;
}
inline explicit operator bool() { return m_ptr != nullptr; }
inline bool operator!() { return m_ptr != nullptr; }
inline reference operator*() { return *m_ptr; }
inline const_reference operator*() const { return *m_ptr; }
inline pointer operator->() { return m_ptr; }
inline const_pointer operator->() const { return m_ptr; }
/**
* @brief Returns the element this iterator points to.
*/
inline pointer ptr() { return m_ptr; }
/**
* @brief Returns the element this iterator points to.
*/
inline const_pointer ptr() const { return m_ptr; }
private:
pointer m_ptr;
};
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator==(bidirectional_iterator<T> const& lhs,
bidirectional_iterator<T> const& rhs)
{
return lhs.ptr() == rhs.ptr();
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator==(bidirectional_iterator<T> const& lhs, T const* rhs)
{
return lhs.ptr() == rhs;
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator==(T const* lhs, bidirectional_iterator<T> const& rhs)
{
return lhs == rhs.ptr();
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator==(bidirectional_iterator<T> const& lhs, decltype(nullptr))
{
return lhs.ptr() == nullptr;
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator==(decltype(nullptr), bidirectional_iterator<T> const& rhs)
{
return rhs.ptr() == nullptr;
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator!=(bidirectional_iterator<T> const& lhs,
bidirectional_iterator<T> const& rhs)
{
return !(lhs == rhs);
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator!=(bidirectional_iterator<T> const& lhs, T const* rhs)
{
return !(lhs == rhs);
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator!=(T const* lhs, bidirectional_iterator<T> const& rhs)
{
return !(lhs == rhs);
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator!=(bidirectional_iterator<T> const& lhs, decltype(nullptr))
{
return !(lhs == nullptr);
}
/**
* @relates bidirectional_iterator
*/
template<class T>
inline bool operator!=(decltype(nullptr), bidirectional_iterator<T> const& rhs)
{
return !(nullptr == rhs);
}
} } // namespace cppa::intrusive
#endif // BIDIRECTIONAL_ITERATOR_HPP
This diff is collapsed.
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <memory> #include <memory>
#include "cppa/detail/thread.hpp" #include "cppa/detail/thread.hpp"
#include "cppa/intrusive/doubly_linked_list.hpp"
namespace cppa { namespace intrusive { namespace cppa { namespace intrusive {
...@@ -60,8 +61,7 @@ class single_reader_queue ...@@ -60,8 +61,7 @@ class single_reader_queue
typedef value_type* pointer; typedef value_type* pointer;
typedef value_type const* const_pointer; typedef value_type const* const_pointer;
typedef std::unique_ptr<value_type> unique_value_ptr; typedef doubly_linked_list<value_type> cache_type;
typedef std::list<unique_value_ptr> cache_type;
typedef typename cache_type::iterator cache_iterator; typedef typename cache_type::iterator cache_iterator;
/** /**
...@@ -240,13 +240,12 @@ class single_reader_queue ...@@ -240,13 +240,12 @@ class single_reader_queue
// next iteration element // next iteration element
pointer next = e->next; pointer next = e->next;
// insert e to private cache (convert to LIFO order) // insert e to private cache (convert to LIFO order)
tmp.push_front(unique_value_ptr{e}); tmp.push_front(e);
//m_cache.insert(iter, unique_value_ptr{e});
// next iteration // next iteration
e = next; e = next;
} }
if (iter) *iter = tmp.begin(); if (iter) *iter = tmp.begin();
m_cache.splice(m_cache.end(), tmp); m_cache.splice(m_cache.end(), std::move(tmp));
return true; return true;
} }
// next iteration // next iteration
...@@ -259,10 +258,7 @@ class single_reader_queue ...@@ -259,10 +258,7 @@ class single_reader_queue
{ {
if (!m_cache.empty() || fetch_new_data()) if (!m_cache.empty() || fetch_new_data())
{ {
auto result = m_cache.front().release(); return m_cache.take(m_cache.begin());
m_cache.pop_front();
return result;
//return m_cache.take_after(m_cache.before_begin());
} }
return nullptr; return nullptr;
} }
......
...@@ -91,9 +91,7 @@ bool abstract_event_based_actor::invoke_from_cache() ...@@ -91,9 +91,7 @@ bool abstract_event_based_actor::invoke_from_cache()
{ {
for (auto i = m_mailbox_pos; i != m_mailbox.cache().end(); ++i) for (auto i = m_mailbox_pos; i != m_mailbox.cache().end(); ++i)
{ {
auto& ptr = *i; if (handle_message(*i))
CPPA_REQUIRE(ptr.get() != nullptr);
if (handle_message(*ptr))
{ {
m_mailbox.cache().erase(i); m_mailbox.cache().erase(i);
return true; return true;
......
...@@ -70,7 +70,7 @@ void converted_thread_context::enqueue(actor* sender, const any_tuple& msg) ...@@ -70,7 +70,7 @@ void converted_thread_context::enqueue(actor* sender, const any_tuple& msg)
void converted_thread_context::dequeue(partial_function& rules) /*override*/ void converted_thread_context::dequeue(partial_function& rules) /*override*/
{ {
auto rm_fun = [&](queue_node_ptr& node) { return dq(*node, rules); }; auto rm_fun = [&](queue_node& node) { return dq(node, rules); };
auto& mbox_cache = m_mailbox.cache(); auto& mbox_cache = m_mailbox.cache();
auto mbox_end = mbox_cache.end(); auto mbox_end = mbox_cache.end();
auto iter = std::find_if(mbox_cache.begin(), mbox_end, rm_fun); auto iter = std::find_if(mbox_cache.begin(), mbox_end, rm_fun);
...@@ -87,9 +87,9 @@ void converted_thread_context::dequeue(behavior& rules) /*override*/ ...@@ -87,9 +87,9 @@ void converted_thread_context::dequeue(behavior& rules) /*override*/
{ {
auto timeout = now(); auto timeout = now();
timeout += rules.timeout(); timeout += rules.timeout();
auto rm_fun = [&](queue_node_ptr& node) auto rm_fun = [&](queue_node& node)
{ {
return dq(*node, rules.get_partial_function()); return dq(node, rules.get_partial_function());
}; };
auto& mbox_cache = m_mailbox.cache(); auto& mbox_cache = m_mailbox.cache();
auto mbox_end = mbox_cache.end(); auto mbox_end = mbox_cache.end();
......
...@@ -52,13 +52,13 @@ mailman_job::mailman_job(process_information_ptr piptr, ...@@ -52,13 +52,13 @@ mailman_job::mailman_job(process_information_ptr piptr,
const actor_ptr& from, const actor_ptr& from,
const channel_ptr& to, const channel_ptr& to,
const any_tuple& content) const any_tuple& content)
: next(nullptr), m_type(send_job_type) : next(nullptr), prev(nullptr), m_type(send_job_type)
{ {
new (&m_send_job) mailman_send_job (piptr, from, to, content); new (&m_send_job) mailman_send_job (piptr, from, to, content);
} }
mailman_job::mailman_job(native_socket_type sockfd, const process_information_ptr& pinfo) mailman_job::mailman_job(native_socket_type sockfd, const process_information_ptr& pinfo)
: next(0), m_type(add_peer_type) : next(nullptr), prev(nullptr), m_type(add_peer_type)
{ {
new (&m_add_socket) mailman_add_peer (sockfd, pinfo); new (&m_add_socket) mailman_add_peer (sockfd, pinfo);
} }
......
...@@ -55,6 +55,7 @@ post_office_msg::post_office_msg(native_socket_type arg0, ...@@ -55,6 +55,7 @@ post_office_msg::post_office_msg(native_socket_type arg0,
const actor_proxy_ptr& arg2, const actor_proxy_ptr& arg2,
std::unique_ptr<attachable>&& arg3) std::unique_ptr<attachable>&& arg3)
: next(nullptr) : next(nullptr)
, prev(nullptr)
, m_type(add_peer_type) , m_type(add_peer_type)
{ {
new (&m_add_peer_msg) add_peer(arg0, arg1, arg2, std::move(arg3)); new (&m_add_peer_msg) add_peer(arg0, arg1, arg2, std::move(arg3));
...@@ -62,6 +63,7 @@ post_office_msg::post_office_msg(native_socket_type arg0, ...@@ -62,6 +63,7 @@ post_office_msg::post_office_msg(native_socket_type arg0,
post_office_msg::post_office_msg(native_socket_type arg0, const actor_ptr& arg1) post_office_msg::post_office_msg(native_socket_type arg0, const actor_ptr& arg1)
: next(nullptr) : next(nullptr)
, prev(nullptr)
, m_type(add_server_socket_type) , m_type(add_server_socket_type)
{ {
new (&m_add_server_socket) add_server_socket(arg0, arg1); new (&m_add_server_socket) add_server_socket(arg0, arg1);
...@@ -69,6 +71,7 @@ post_office_msg::post_office_msg(native_socket_type arg0, const actor_ptr& arg1) ...@@ -69,6 +71,7 @@ post_office_msg::post_office_msg(native_socket_type arg0, const actor_ptr& arg1)
post_office_msg::post_office_msg(const actor_proxy_ptr& proxy_ptr) post_office_msg::post_office_msg(const actor_proxy_ptr& proxy_ptr)
: next(nullptr) : next(nullptr)
, prev(nullptr)
, m_type(proxy_exited_type) , m_type(proxy_exited_type)
{ {
new (&m_proxy_exited) proxy_exited(proxy_ptr); new (&m_proxy_exited) proxy_exited(proxy_ptr);
......
...@@ -98,7 +98,7 @@ void yielding_actor::yield_until_not_empty() ...@@ -98,7 +98,7 @@ void yielding_actor::yield_until_not_empty()
void yielding_actor::dequeue(partial_function& fun) void yielding_actor::dequeue(partial_function& fun)
{ {
auto rm_fun = [&](queue_node_ptr& node) { return dq(*node, fun) == dq_done; }; auto rm_fun = [&](queue_node& node) { return dq(node, fun) == dq_done; };
dequeue_impl(rm_fun); dequeue_impl(rm_fun);
} }
...@@ -107,9 +107,9 @@ void yielding_actor::dequeue(behavior& bhvr) ...@@ -107,9 +107,9 @@ void yielding_actor::dequeue(behavior& bhvr)
if (bhvr.timeout().valid()) if (bhvr.timeout().valid())
{ {
request_timeout(bhvr.timeout()); request_timeout(bhvr.timeout());
auto rm_fun = [&](queue_node_ptr& node) -> bool auto rm_fun = [&](queue_node& node) -> bool
{ {
switch (dq(*node, bhvr.get_partial_function())) switch (dq(node, bhvr.get_partial_function()))
{ {
case dq_timeout_occured: case dq_timeout_occured:
bhvr.handle_timeout(); bhvr.handle_timeout();
......
...@@ -42,8 +42,9 @@ namespace { size_t s_iint_instances = 0; } ...@@ -42,8 +42,9 @@ namespace { size_t s_iint_instances = 0; }
struct iint struct iint
{ {
iint* next; iint* next;
iint* prev;
int value; int value;
inline iint(int val = 0) : next(nullptr), value(val) { ++s_iint_instances; } inline iint(int val = 0) : next(0), prev(0), value(val) { ++s_iint_instances; }
~iint() { --s_iint_instances; } ~iint() { --s_iint_instances; }
}; };
...@@ -63,11 +64,28 @@ inline bool operator==(int lhs, iint const& rhs) ...@@ -63,11 +64,28 @@ inline bool operator==(int lhs, iint const& rhs)
} }
typedef cppa::intrusive::singly_linked_list<iint> iint_list; typedef cppa::intrusive::singly_linked_list<iint> iint_list;
typedef cppa::intrusive::doubly_linked_list<iint> diint_list;
typedef cppa::intrusive::single_reader_queue<iint> iint_queue; typedef cppa::intrusive::single_reader_queue<iint> iint_queue;
size_t test__intrusive_containers() size_t test__intrusive_containers()
{ {
CPPA_TEST(test__intrusive_containers); CPPA_TEST(test__intrusive_containers);
{
diint_list dlist1;
dlist1.emplace_back(1);
dlist1.emplace_back(2);
dlist1.emplace_back(3);
CPPA_CHECK_EQUAL(1, dlist1.front().value);
CPPA_CHECK_EQUAL(3, dlist1.back().value);
dlist1.remove_if([](iint const& i) { return i.value % 2 == 1; });
CPPA_CHECK_EQUAL(2, dlist1.front().value);
CPPA_CHECK_EQUAL(2, dlist1.back().value);
dlist1.erase(dlist1.begin());
CPPA_CHECK(dlist1.empty());
}
iint_list ilist1; iint_list ilist1;
ilist1.push_back(new iint(1)); ilist1.push_back(new iint(1));
ilist1.emplace_back(2); ilist1.emplace_back(2);
......
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