Skip to content

Commit

Permalink
Merge pull request #168 from cocaine/startup-signals
Browse files Browse the repository at this point in the history
[Core] Retroactive signals.
  • Loading branch information
Andrey Sibiryov committed Mar 17, 2015
2 parents 26cbd93 + 1dc37de commit 5741eff
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 8 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ language: cpp
compiler:
- gcc
before_install:
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get update -qq
install:
- sudo apt-get install -qq g++-4.8 devscripts build-essential equivs python-software-properties
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90
- sudo apt-get install -qq devscripts build-essential equivs python-software-properties
notifications:
slack: cocaine:qDewv6ZVDt0TciQeNdE47GqG
script: "tests/ci/travis.sh"
9 changes: 4 additions & 5 deletions include/cocaine/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "cocaine/locked_ptr.hpp"
#include "cocaine/repository.hpp"
#include "cocaine/signal.hpp"

#include <blackhole/blackhole.hpp>

Expand Down Expand Up @@ -102,8 +103,8 @@ struct config_t {
// Dynamic port mapper

class port_mapping_t {
// Pinned service ports.
std::map<std::string, port_t> const m_pinned;
const
std::map<std::string, port_t> m_pinned;

// Ports available for dynamic allocation.
std::deque<port_t> m_shared;
Expand All @@ -127,8 +128,6 @@ class port_mapping_t {

// Context

namespace signals = boost::signals2;

class actor_t;
class execution_unit_t;

Expand Down Expand Up @@ -164,7 +163,7 @@ class context_t {

struct signals_t {
typedef signals::signal<void()> context_signals_t;
typedef signals::signal<void(const actor_t& service)> service_signals_t;
typedef cocaine::retroactive_signal<void(const actor_t& service)> service_signals_t;

struct {
// Fired on service creation, after service's thread is launched and is ready to accept
Expand Down
95 changes: 95 additions & 0 deletions include/cocaine/signal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
Copyright (c) 2011-2014 Andrey Sibiryov <[email protected]>
Copyright (c) 2011-2014 Other contributors as noted in the AUTHORS file.
This file is part of Cocaine.
Cocaine 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.
Cocaine 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef COCAINE_SIGNAL_HPP
#define COCAINE_SIGNAL_HPP

#include "cocaine/tuple.hpp"

#include <algorithm>
#include <list>
#include <mutex>

#define BOOST_BIND_NO_PLACEHOLDERS
#include <boost/signals2/signal.hpp>

namespace cocaine {

namespace signals = boost::signals2;

template<
class Signature,
class IndexSequence = typename make_index_sequence<signals::signal<Signature>::arity>::type
>
class retroactive_signal;

template<typename... Args, size_t... Indices>
class retroactive_signal<void(Args...), index_sequence<Indices...>> {
typedef signals::signal<void(Args...)> signal_type;

// The actual underlying signal object.
signal_type wrapped;

// Deferred signal arguments.
mutable std::list<std::tuple<Args...>> history;
mutable std::mutex mutex;

public:
typedef typename signal_type::slot_type slot_type;

auto
connect(const slot_type& slot) -> signals::connection {
try {
std::lock_guard<std::mutex> guard(mutex);

std::for_each(history.begin(), history.end(), [&slot](const std::tuple<Args...>& args) {
slot(std::get<Indices>(args)...);
});
} catch(const signals::expired_slot& e) {
return signals::connection();
}

return wrapped.connect(slot);
}

void
operator()(Args&&... args) {
{
std::lock_guard<std::mutex> guard(mutex);
history.emplace_back(std::forward<Args>(args)...);
}

wrapped(std::forward<Args>(args)...);
}

void
operator()(Args&&... args) const {
{
std::lock_guard<std::mutex> guard(mutex);
history.emplace_back(std::forward<Args>(args)...);
}

wrapped(std::forward<Args>(args)...);
}
};

} // namespace cocaine

#endif

0 comments on commit 5741eff

Please sign in to comment.