nixd
Toggle main menu visibility
Loading...
Searching...
No Matches
nixd
lspserver
include
lspserver
Function.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <llvm/ADT/FunctionExtras.h>
4
#include <llvm/Support/Error.h>
5
#include <mutex>
6
#include <tuple>
7
#include <utility>
8
9
namespace
lspserver
{
10
11
/// A Callback<T> is a void function that accepts Expected<T>.
12
/// This is accepted by ClangdServer functions that logically return T.
13
template
<
typename
T>
14
using
Callback
= llvm::unique_function<void(llvm::Expected<T>)>;
15
16
/// An Event<T> allows events of type T to be broadcast to listeners.
17
template
<
typename
T>
class
Event
{
18
public
:
19
// A Listener is the callback through which events are delivered.
20
using
Listener
= std::function<void(
const
T &)>;
21
22
// A subscription defines the scope of when a listener should receive events.
23
// After destroying the subscription, no more events are received.
24
class
[[nodiscard]] Subscription {
25
Event *Parent;
26
unsigned
ListenerID;
27
28
Subscription(Event *Parent,
unsigned
ListenerID)
29
: Parent(Parent), ListenerID(ListenerID) {}
30
friend
Event;
31
32
public
:
33
Subscription
() : Parent(nullptr) {}
34
Subscription
(Subscription &&Other) : Parent(nullptr) {
35
*
this
= std::move(Other);
36
}
37
Subscription &
operator=
(Subscription &&Other) {
38
// If *this is active, unsubscribe.
39
if
(Parent) {
40
std::lock_guard<std::recursive_mutex> Lock(Parent->ListenersMu);
41
llvm::erase_if(Parent->Listeners,
42
[&](
const
std::pair<Listener, unsigned> &P) {
43
return P.second == ListenerID;
44
});
45
}
46
// Take over the other subscription, and mark it inactive.
47
std::tie(Parent, ListenerID) = std::tie(Other.Parent, Other.ListenerID);
48
Other.Parent =
nullptr
;
49
return
*
this
;
50
}
51
// Destroying a subscription may block if an event is being broadcast.
52
~Subscription
() {
53
if
(Parent)
54
*
this
= Subscription();
// Unsubscribe.
55
}
56
};
57
58
// Adds a listener that will observe all future events until the returned
59
// subscription is destroyed.
60
// May block if an event is currently being broadcast.
61
Subscription
observe
(
Listener
L) {
62
std::lock_guard<std::recursive_mutex> Lock(ListenersMu);
63
Listeners.push_back({std::move(L), ++ListenerCount});
64
return
Subscription
(
this
, ListenerCount);
65
}
66
67
// Synchronously sends an event to all registered listeners.
68
// Must not be called from a listener to this event.
69
void
broadcast
(
const
T &V) {
70
// FIXME: it would be nice to dynamically check non-reentrancy here.
71
std::lock_guard<std::recursive_mutex> Lock(ListenersMu);
72
for
(
const
auto
&L : Listeners)
73
L.first(V);
74
}
75
76
~Event
() {
77
std::lock_guard<std::recursive_mutex> Lock(ListenersMu);
78
assert(Listeners.empty());
79
}
80
81
private
:
82
static_assert
(std::is_same<std::decay_t<T>, T>::value,
83
"use a plain type: event values are always passed by const&"
);
84
85
std::recursive_mutex ListenersMu;
86
bool
IsBroadcasting =
false
;
87
std::vector<std::pair<Listener, unsigned>> Listeners;
88
unsigned
ListenerCount = 0;
89
};
90
91
}
// namespace lspserver
lspserver::Event::Subscription
Definition
Function.h:24
lspserver::Event::Subscription::Subscription
Subscription(Subscription &&Other)
Definition
Function.h:34
lspserver::Event::Subscription::~Subscription
~Subscription()
Definition
Function.h:52
lspserver::Event::Subscription::operator=
Subscription & operator=(Subscription &&Other)
Definition
Function.h:37
lspserver::Event::Subscription::Subscription
Subscription()
Definition
Function.h:33
lspserver::Event
An Event<T> allows events of type T to be broadcast to listeners.
Definition
Function.h:17
lspserver::Event::broadcast
void broadcast(const T &V)
Definition
Function.h:69
lspserver::Event::Listener
std::function< void(const T &)> Listener
Definition
Function.h:20
lspserver::Event::observe
Subscription observe(Listener L)
Definition
Function.h:61
lspserver::Event::~Event
~Event()
Definition
Function.h:76
lspserver
Whether current platform treats paths case insensitively.
Definition
Connection.h:11
lspserver::Callback
llvm::unique_function< void(llvm::Expected< T >)> Callback
Definition
Function.h:14
Generated by
1.17.0