1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#ifndef ServiceRegistry_connect_but_block_self_h
#define ServiceRegistry_connect_but_block_self_h
// -*- C++ -*-
//
// Package: ServiceRegistry
// Class : connect_but_block_self
//
/**\function connect_but_block_self connect_but_block_self.h FWCore/ServiceRegistry/interface/connect_but_block_self.h
Description: Connects a functional object to a signal, but guarantees that the functional object will never see a
signal caused by its own action.
Usage:
<usage>
*/
//
// Original Author: Chris Jones
// Created: Thu Sep 22 20:42:32 CEST 2005
//
// system include files
#include <memory>
#include "FWCore/Utilities/interface/Signal.h"
// user include files
// forward declarations
namespace edm {
namespace serviceregistry {
template <typename Func>
class BlockingWrapper {
public:
BlockingWrapper(Func iFunc) : func_(iFunc), numBlocks_(0) {}
//virtual ~BlockingWrapper();
// ---------- const member functions ---------------------
template <typename... Args>
void operator()(Args&&... args) {
std::shared_ptr<void> guard(static_cast<void*>(nullptr), std::bind(&BlockingWrapper::unblock, this));
if (startBlocking()) {
func_(std::forward<Args>(args)...);
}
}
// ---------- static member functions --------------------
// ---------- member functions ---------------------------
private:
// ---------- member data --------------------------------
bool startBlocking() { return 1 == ++numBlocks_; }
void unblock() { --numBlocks_; }
Func func_;
int numBlocks_;
};
template <class Func, class Signal>
void connect_but_block_self(Signal& oSignal, const Func& iFunc) {
oSignal.connect(BlockingWrapper<Func>(iFunc));
}
} // namespace serviceregistry
} // namespace edm
#endif
|