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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
/*
* Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_INSTANCE_HXX
#define MPD_INSTANCE_HXX
#include "config.h"
#include "event/Loop.hxx"
#include "event/Thread.hxx"
#include "event/MaskMonitor.hxx"
#include "util/Compiler.h"
#ifdef ENABLE_SYSTEMD_DAEMON
#include "lib/systemd/Watchdog.hxx"
#endif
#ifdef ENABLE_CURL
#include "RemoteTagCacheHandler.hxx"
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
#include "neighbor/Listener.hxx"
class NeighborGlue;
#endif
#ifdef ENABLE_DATABASE
#include "db/DatabaseListener.hxx"
class Database;
class Storage;
class UpdateService;
#endif
#include <memory>
#include <list>
class ClientList;
struct Partition;
class StateFile;
class RemoteTagCache;
/**
* A utility class which, when used as the first base class, ensures
* that the #EventLoop gets initialized before the other base classes.
*/
struct EventLoopHolder {
EventLoop event_loop;
};
struct Instance final
: EventLoopHolder
#if defined(ENABLE_DATABASE) || defined(ENABLE_NEIGHBOR_PLUGINS)
,
#endif
#ifdef ENABLE_DATABASE
public DatabaseListener
#ifdef ENABLE_NEIGHBOR_PLUGINS
,
#endif
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
public NeighborListener
#endif
#ifdef ENABLE_CURL
, public RemoteTagCacheHandler
#endif
{
/**
* A thread running an #EventLoop for non-blocking (bulk) I/O.
*/
EventThread io_thread;
/**
* Another thread running an #EventLoop for non-blocking
* (real-time) I/O. This is used instead of #io_thread for
* events which require low latency, e.g. for filling hardware
* ring buffers.
*/
EventThread rtio_thread;
#ifdef ENABLE_SYSTEMD_DAEMON
Systemd::Watchdog systemd_watchdog;
#endif
MaskMonitor idle_monitor;
#ifdef ENABLE_NEIGHBOR_PLUGINS
NeighborGlue *neighbors;
#endif
#ifdef ENABLE_DATABASE
Database *database;
/**
* This is really a #CompositeStorage. To avoid heavy include
* dependencies, we declare it as just #Storage.
*/
Storage *storage = nullptr;
UpdateService *update = nullptr;
#endif
#ifdef ENABLE_CURL
std::unique_ptr<RemoteTagCache> remote_tag_cache;
#endif
ClientList *client_list;
std::list<Partition> partitions;
StateFile *state_file = nullptr;
Instance();
~Instance() noexcept;
/**
* Wrapper for EventLoop::Break(). Call to initiate shutdown.
*/
void Break() {
event_loop.Break();
}
void EmitIdle(unsigned mask) {
idle_monitor.OrMask(mask);
}
/**
* Find a #Partition with the given name. Returns nullptr if
* no such partition was found.
*/
gcc_pure
Partition *FindPartition(const char *name) noexcept;
void BeginShutdownPartitions() noexcept;
void FinishShutdownPartitions() noexcept;
#ifdef ENABLE_DATABASE
/**
* Returns the global #Database instance. May return nullptr
* if this MPD configuration has no database (no
* music_directory was configured).
*/
Database *GetDatabase() {
return database;
}
/**
* Returns the global #Database instance. Throws
* DatabaseError if this MPD configuration has no database (no
* music_directory was configured).
*/
const Database &GetDatabaseOrThrow() const;
#endif
void BeginShutdownUpdate() noexcept;
void FinishShutdownUpdate() noexcept;
void ShutdownDatabase() noexcept;
#ifdef ENABLE_CURL
void LookupRemoteTag(const char *uri) noexcept;
#else
void LookupRemoteTag(const char *) noexcept {
/* no-op */
}
#endif
private:
#ifdef ENABLE_DATABASE
void OnDatabaseModified() override;
void OnDatabaseSongRemoved(const char *uri) override;
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
/* virtual methods from class NeighborListener */
void FoundNeighbor(const NeighborInfo &info) noexcept override;
void LostNeighbor(const NeighborInfo &info) noexcept override;
#endif
#ifdef ENABLE_CURL
/* virtual methods from class RemoteTagCacheHandler */
void OnRemoteTag(const char *uri, const Tag &tag) noexcept override;
#endif
/* callback for #idle_monitor */
void OnIdle(unsigned mask);
};
#endif
|