Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
5a4055fb
Commit
5a4055fb
authored
Oct 14, 2020
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event/SocketMonitor: refactor to SocketEvent
Similar to commits
1686f4e8
and
30a5dd26
parent
4d68a12f
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
282 additions
and
261 deletions
+282
-261
ProxyDatabasePlugin.cxx
src/db/plugins/ProxyDatabasePlugin.cxx
+14
-16
InotifySource.cxx
src/db/update/InotifySource.cxx
+7
-9
InotifySource.hxx
src/db/update/InotifySource.hxx
+6
-4
BufferedSocket.cxx
src/event/BufferedSocket.cxx
+9
-11
BufferedSocket.hxx
src/event/BufferedSocket.hxx
+26
-10
FullyBufferedSocket.cxx
src/event/FullyBufferedSocket.cxx
+8
-8
FullyBufferedSocket.hxx
src/event/FullyBufferedSocket.hxx
+3
-3
Loop.cxx
src/event/Loop.cxx
+9
-11
Loop.hxx
src/event/Loop.hxx
+12
-14
MultiSocketMonitor.hxx
src/event/MultiSocketMonitor.hxx
+18
-16
ServerSocket.cxx
src/event/ServerSocket.cxx
+19
-12
SignalMonitor.cxx
src/event/SignalMonitor.cxx
+15
-13
SocketEvent.cxx
src/event/SocketEvent.cxx
+8
-8
SocketEvent.hxx
src/event/SocketEvent.hxx
+17
-18
UringManager.cxx
src/event/UringManager.cxx
+1
-3
UringManager.hxx
src/event/UringManager.hxx
+7
-6
meson.build
src/event/meson.build
+1
-1
Global.cxx
src/lib/curl/Global.cxx
+24
-14
Watch.cxx
src/lib/dbus/Watch.cxx
+12
-13
Watch.hxx
src/lib/dbus/Watch.hxx
+5
-4
Connection.cxx
src/lib/nfs/Connection.cxx
+16
-23
Connection.hxx
src/lib/nfs/Connection.hxx
+9
-7
HttpdClient.cxx
src/output/plugins/httpd/HttpdClient.cxx
+8
-11
HttpdClient.hxx
src/output/plugins/httpd/HttpdClient.hxx
+2
-2
AvahiPoll.cxx
src/zeroconf/AvahiPoll.cxx
+15
-16
ZeroconfBonjour.cxx
src/zeroconf/ZeroconfBonjour.cxx
+11
-8
No files found.
src/db/plugins/ProxyDatabasePlugin.cxx
View file @
5a4055fb
...
...
@@ -42,7 +42,7 @@
#include "util/ScopeExit.hxx"
#include "util/RuntimeError.hxx"
#include "protocol/Ack.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "event/IdleEvent.hxx"
#include "Log.hxx"
...
...
@@ -85,7 +85,8 @@ public:
}
};
class
ProxyDatabase
final
:
public
Database
,
SocketMonitor
{
class
ProxyDatabase
final
:
public
Database
{
SocketEvent
socket_event
;
IdleEvent
idle_event
;
DatabaseListener
&
listener
;
...
...
@@ -149,10 +150,8 @@ private:
void
Disconnect
()
noexcept
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
void
OnIdle
()
noexcept
;
/* virtual methods from SocketMonitor */
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
};
static
constexpr
struct
{
...
...
@@ -446,7 +445,7 @@ SendGroup(mpd_connection *connection, ConstBuffer<TagType> group)
ProxyDatabase
::
ProxyDatabase
(
EventLoop
&
_loop
,
DatabaseListener
&
_listener
,
const
ConfigBlock
&
block
)
:
Database
(
proxy_db_plugin
),
SocketMonitor
(
_loop
),
socket_event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
)
),
idle_event
(
_loop
,
BIND_THIS_METHOD
(
OnIdle
)),
listener
(
_listener
),
host
(
block
.
GetBlockValue
(
"host"
,
""
)),
...
...
@@ -527,7 +526,7 @@ ProxyDatabase::Connect()
idle_received
=
~
0U
;
is_idle
=
false
;
SocketMonitor
::
Open
(
SocketDescriptor
(
mpd_async_get_fd
(
mpd_connection_get_async
(
connection
))));
socket_event
.
Open
(
SocketDescriptor
(
mpd_async_get_fd
(
mpd_connection_get_async
(
connection
))));
idle_event
.
Schedule
();
}
...
...
@@ -574,13 +573,13 @@ ProxyDatabase::Disconnect() noexcept
assert
(
connection
!=
nullptr
);
idle_event
.
Cancel
();
SocketMonitor
::
Steal
();
socket_event
.
Steal
();
mpd_connection_free
(
connection
);
connection
=
nullptr
;
}
bool
void
ProxyDatabase
::
OnSocketReady
([[
maybe_unused
]]
unsigned
flags
)
noexcept
{
assert
(
connection
!=
nullptr
);
...
...
@@ -588,8 +587,8 @@ ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept
if
(
!
is_idle
)
{
// TODO: can this happen?
idle_event
.
Schedule
();
SocketMonitor
::
Cancel
();
return
true
;
socket_event
.
Cancel
();
return
;
}
auto
idle
=
(
unsigned
)
mpd_recv_idle
(
connection
,
false
);
...
...
@@ -599,7 +598,7 @@ ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept
}
catch
(...)
{
LogError
(
std
::
current_exception
());
Disconnect
();
return
false
;
return
;
}
}
...
...
@@ -607,8 +606,7 @@ ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept
idle_received
|=
idle
;
is_idle
=
false
;
idle_event
.
Schedule
();
SocketMonitor
::
Cancel
();
return
true
;
socket_event
.
Cancel
();
}
void
...
...
@@ -636,14 +634,14 @@ ProxyDatabase::OnIdle() noexcept
LogError
(
std
::
current_exception
());
}
SocketMonitor
::
Steal
();
socket_event
.
Steal
();
mpd_connection_free
(
connection
);
connection
=
nullptr
;
return
;
}
is_idle
=
true
;
SocketMonitor
::
ScheduleRead
();
socket_event
.
ScheduleRead
();
}
const
LightSong
*
...
...
src/db/update/InotifySource.cxx
View file @
5a4055fb
...
...
@@ -30,14 +30,14 @@
#include <sys/inotify.h>
bool
void
InotifySource
::
OnSocketReady
([[
maybe_unused
]]
unsigned
flags
)
noexcept
{
uint8_t
buffer
[
4096
];
static_assert
(
sizeof
(
buffer
)
>=
sizeof
(
struct
inotify_event
)
+
NAME_MAX
+
1
,
"inotify buffer too small"
);
auto
ifd
=
GetSocket
().
ToFileDescriptor
();
auto
ifd
=
socket_event
.
GetSocket
().
ToFileDescriptor
();
ssize_t
nbytes
=
ifd
.
Read
(
buffer
,
sizeof
(
buffer
));
if
(
nbytes
<
0
)
FatalSystemError
(
"Failed to read from inotify"
);
...
...
@@ -63,8 +63,6 @@ InotifySource::OnSocketReady([[maybe_unused]] unsigned flags) noexcept
callback
(
event
->
wd
,
event
->
mask
,
name
,
callback_ctx
);
p
+=
sizeof
(
*
event
)
+
event
->
len
;
}
return
true
;
}
static
FileDescriptor
...
...
@@ -79,17 +77,17 @@ InotifyInit()
InotifySource
::
InotifySource
(
EventLoop
&
_loop
,
mpd_inotify_callback_t
_callback
,
void
*
_ctx
)
:
SocketMonitor
(
SocketDescriptor
::
FromFileDescriptor
(
InotifyInit
()
),
_loop
),
:
socket_event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
),
SocketDescriptor
::
FromFileDescriptor
(
InotifyInit
())
),
callback
(
_callback
),
callback_ctx
(
_ctx
)
{
ScheduleRead
();
socket_event
.
ScheduleRead
();
}
int
InotifySource
::
Add
(
const
char
*
path_fs
,
unsigned
mask
)
{
auto
ifd
=
GetSocket
().
ToFileDescriptor
();
auto
ifd
=
socket_event
.
GetSocket
().
ToFileDescriptor
();
int
wd
=
inotify_add_watch
(
ifd
.
Get
(),
path_fs
,
mask
);
if
(
wd
<
0
)
throw
MakeErrno
(
"inotify_add_watch() has failed"
);
...
...
@@ -100,7 +98,7 @@ InotifySource::Add(const char *path_fs, unsigned mask)
void
InotifySource
::
Remove
(
unsigned
wd
)
noexcept
{
auto
ifd
=
GetSocket
().
ToFileDescriptor
();
auto
ifd
=
socket_event
.
GetSocket
().
ToFileDescriptor
();
int
ret
=
inotify_rm_watch
(
ifd
.
Get
(),
wd
);
if
(
ret
<
0
&&
errno
!=
EINVAL
)
LogErrno
(
inotify_domain
,
"inotify_rm_watch() has failed"
);
...
...
src/db/update/InotifySource.hxx
View file @
5a4055fb
...
...
@@ -20,12 +20,14 @@
#ifndef MPD_INOTIFY_SOURCE_HXX
#define MPD_INOTIFY_SOURCE_HXX
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
typedef
void
(
*
mpd_inotify_callback_t
)(
int
wd
,
unsigned
mask
,
const
char
*
name
,
void
*
ctx
);
class
InotifySource
final
:
private
SocketMonitor
{
class
InotifySource
final
{
SocketEvent
socket_event
;
mpd_inotify_callback_t
callback
;
void
*
callback_ctx
;
...
...
@@ -43,7 +45,7 @@ public:
mpd_inotify_callback_t
callback
,
void
*
ctx
);
~
InotifySource
()
noexcept
{
Close
();
socket_event
.
Close
();
}
/**
...
...
@@ -63,7 +65,7 @@ public:
void
Remove
(
unsigned
wd
)
noexcept
;
private
:
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
};
#endif
src/event/BufferedSocket.cxx
View file @
5a4055fb
...
...
@@ -69,7 +69,7 @@ BufferedSocket::ResumeInput() noexcept
while
(
true
)
{
const
auto
buffer
=
input
.
Read
();
if
(
buffer
.
empty
())
{
ScheduleRead
();
event
.
ScheduleRead
();
return
true
;
}
...
...
@@ -81,11 +81,11 @@ BufferedSocket::ResumeInput() noexcept
return
false
;
}
ScheduleRead
();
event
.
ScheduleRead
();
return
true
;
case
InputResult
:
:
PAUSE
:
CancelRead
();
event
.
CancelRead
();
return
true
;
case
InputResult
:
:
AGAIN
:
...
...
@@ -97,25 +97,23 @@ BufferedSocket::ResumeInput() noexcept
}
}
bool
void
BufferedSocket
::
OnSocketReady
(
unsigned
flags
)
noexcept
{
assert
(
IsDefined
());
if
(
gcc_unlikely
(
flags
&
(
ERROR
|
HANGUP
)))
{
if
(
gcc_unlikely
(
flags
&
(
SocketEvent
::
ERROR
|
SocketEvent
::
HANGUP
)))
{
OnSocketClosed
();
return
false
;
return
;
}
if
(
flags
&
READ
)
{
if
(
flags
&
SocketEvent
::
READ
)
{
assert
(
!
input
.
IsFull
());
if
(
!
ReadToBuffer
()
||
!
ResumeInput
())
return
false
;
return
;
if
(
!
input
.
IsFull
())
ScheduleRead
();
event
.
ScheduleRead
();
}
return
true
;
}
src/event/BufferedSocket.hxx
View file @
5a4055fb
...
...
@@ -20,7 +20,7 @@
#ifndef MPD_BUFFERED_SOCKET_HXX
#define MPD_BUFFERED_SOCKET_HXX
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "util/StaticFifoBuffer.hxx"
#include <cassert>
...
...
@@ -30,20 +30,37 @@
class
EventLoop
;
/**
* A #Socket
Monitor
specialization that adds an input buffer.
* A #Socket
Event
specialization that adds an input buffer.
*/
class
BufferedSocket
:
protected
SocketMonitor
{
class
BufferedSocket
{
StaticFifoBuffer
<
uint8_t
,
8192
>
input
;
protected
:
SocketEvent
event
;
public
:
using
ssize_t
=
SocketEvent
::
ssize_t
;
BufferedSocket
(
SocketDescriptor
_fd
,
EventLoop
&
_loop
)
noexcept
:
SocketMonitor
(
_fd
,
_loop
)
{
ScheduleRead
();
:
event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
),
_fd
)
{
event
.
ScheduleRead
();
}
auto
&
GetEventLoop
()
const
noexcept
{
return
event
.
GetEventLoop
();
}
using
SocketMonitor
::
GetEventLoop
;
using
SocketMonitor
::
IsDefined
;
using
SocketMonitor
::
Close
;
bool
IsDefined
()
const
noexcept
{
return
event
.
IsDefined
();
}
auto
GetSocket
()
const
noexcept
{
return
event
.
GetSocket
();
}
void
Close
()
noexcept
{
event
.
Close
();
}
private
:
/**
...
...
@@ -116,8 +133,7 @@ protected:
virtual
void
OnSocketError
(
std
::
exception_ptr
ep
)
noexcept
=
0
;
virtual
void
OnSocketClosed
()
noexcept
=
0
;
/* virtual methods from class SocketMonitor */
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
virtual
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
};
#endif
src/event/FullyBufferedSocket.cxx
View file @
5a4055fb
...
...
@@ -35,7 +35,7 @@ FullyBufferedSocket::DirectWrite(const void *data, size_t length) noexcept
return
0
;
idle_event
.
Cancel
();
BufferedSocket
::
Cancel
();
event
.
Cancel
();
if
(
IsSocketErrorClosed
(
code
))
OnSocketClosed
();
...
...
@@ -54,7 +54,7 @@ FullyBufferedSocket::Flush() noexcept
const
auto
data
=
output
.
Read
();
if
(
data
.
empty
())
{
idle_event
.
Cancel
();
CancelWrite
();
event
.
CancelWrite
();
return
true
;
}
...
...
@@ -66,7 +66,7 @@ FullyBufferedSocket::Flush() noexcept
if
(
output
.
empty
())
{
idle_event
.
Cancel
();
CancelWrite
();
event
.
CancelWrite
();
}
return
true
;
...
...
@@ -92,23 +92,23 @@ FullyBufferedSocket::Write(const void *data, size_t length) noexcept
return
true
;
}
bool
void
FullyBufferedSocket
::
OnSocketReady
(
unsigned
flags
)
noexcept
{
if
(
flags
&
WRITE
)
{
if
(
flags
&
SocketEvent
::
WRITE
)
{
assert
(
!
output
.
empty
());
assert
(
!
idle_event
.
IsActive
());
if
(
!
Flush
())
return
false
;
return
;
}
return
BufferedSocket
::
OnSocketReady
(
flags
);
BufferedSocket
::
OnSocketReady
(
flags
);
}
void
FullyBufferedSocket
::
OnIdle
()
noexcept
{
if
(
Flush
()
&&
!
output
.
empty
())
ScheduleWrite
();
event
.
ScheduleWrite
();
}
src/event/FullyBufferedSocket.hxx
View file @
5a4055fb
...
...
@@ -69,10 +69,10 @@ protected:
*/
bool
Write
(
const
void
*
data
,
size_t
length
)
noexcept
;
/* virtual methods from class SocketMonitor */
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnIdle
()
noexcept
;
/* virtual methods from class BufferedSocket */
void
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
};
#endif
src/event/Loop.cxx
View file @
5a4055fb
...
...
@@ -19,7 +19,7 @@
#include "Loop.hxx"
#include "TimerEvent.hxx"
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "IdleEvent.hxx"
#include "util/ScopeExit.hxx"
...
...
@@ -47,7 +47,7 @@ EventLoop::EventLoop(
)
:
#ifdef HAVE_THREADED_EVENT_LOOP
SocketMonitor
(
*
this
),
wake_event
(
*
this
,
BIND_THIS_METHOD
(
OnSocketReady
)
),
thread
(
_thread
),
/* if this instance is hosted by an EventThread (no ThreadId
known yet) then we're not yet alive until the thread is
...
...
@@ -59,7 +59,7 @@ EventLoop::EventLoop(
quit
(
false
)
{
#ifdef HAVE_THREADED_EVENT_LOOP
SocketMonitor
::
Open
(
SocketDescriptor
(
wake_fd
.
Get
()));
wake_event
.
Open
(
SocketDescriptor
(
wake_fd
.
Get
()));
#endif
}
...
...
@@ -198,7 +198,7 @@ EventLoop::Run() noexcept
assert
(
alive
);
assert
(
busy
);
SocketMonitor
::
Schedule
(
SocketMonitor
::
READ
);
wake_event
.
Schedule
(
SocketEvent
::
READ
);
#endif
#ifdef HAVE_URING
...
...
@@ -214,7 +214,7 @@ EventLoop::Run() noexcept
#ifdef HAVE_THREADED_EVENT_LOOP
AtScopeExit
(
this
)
{
SocketMonitor
::
Cancel
();
wake_event
.
Cancel
();
};
#endif
...
...
@@ -262,9 +262,9 @@ EventLoop::Run() noexcept
ready_sockets
.
clear
();
for
(
size_t
i
=
0
;
i
<
poll_result
.
GetSize
();
++
i
)
{
auto
&
s
m
=
*
(
SocketMonitor
*
)
poll_result
.
GetObject
(
i
);
s
m
.
SetReadyFlags
(
poll_result
.
GetEvents
(
i
));
ready_sockets
.
push_back
(
s
m
);
auto
&
s
=
*
(
SocketEvent
*
)
poll_result
.
GetObject
(
i
);
s
.
SetReadyFlags
(
poll_result
.
GetEvents
(
i
));
ready_sockets
.
push_back
(
s
);
}
now
=
std
::
chrono
::
steady_clock
::
now
();
...
...
@@ -339,7 +339,7 @@ EventLoop::HandleDeferred() noexcept
}
}
bool
void
EventLoop
::
OnSocketReady
([[
maybe_unused
]]
unsigned
flags
)
noexcept
{
assert
(
IsInside
());
...
...
@@ -348,8 +348,6 @@ EventLoop::OnSocketReady([[maybe_unused]] unsigned flags) noexcept
const
std
::
lock_guard
<
Mutex
>
lock
(
mutex
);
HandleDeferred
();
return
true
;
}
#endif
src/event/Loop.hxx
View file @
5a4055fb
...
...
@@ -22,7 +22,7 @@
#include "Chrono.hxx"
#include "PollGroup.hxx"
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "event/Features.h"
#include "util/Compiler.h"
...
...
@@ -56,15 +56,13 @@ class DeferEvent;
* thread that runs it, except where explicitly documented as
* thread-safe.
*
* @see Socket
Monitor
, MultiSocketMonitor, TimerEvent, IdleEvent
* @see Socket
Event
, MultiSocketMonitor, TimerEvent, IdleEvent
*/
class
EventLoop
final
#ifdef HAVE_THREADED_EVENT_LOOP
:
SocketMonitor
#endif
{
#ifdef HAVE_THREADED_EVENT_LOOP
WakeFD
wake_fd
;
SocketEvent
wake_event
;
#endif
struct
TimerCompare
{
...
...
@@ -96,14 +94,14 @@ class EventLoop final
#endif
using
ReadySocketList
=
boost
::
intrusive
::
list
<
Socket
Monitor
,
boost
::
intrusive
::
member_hook
<
Socket
Monitor
,
Socket
Monitor
::
ReadyListHook
,
&
Socket
Monitor
::
ready_siblings
>
,
boost
::
intrusive
::
list
<
Socket
Event
,
boost
::
intrusive
::
member_hook
<
Socket
Event
,
Socket
Event
::
ReadyListHook
,
&
Socket
Event
::
ready_siblings
>
,
boost
::
intrusive
::
constant_time_size
<
false
>>
;
/**
* A linked list of #Socket
Monitor
instances which have a
* A linked list of #Socket
Event
instances which have a
* non-zero "ready_flags" field, and need to be dispatched.
*/
ReadySocketList
ready_sockets
;
...
...
@@ -190,7 +188,7 @@ public:
*/
void
Break
()
noexcept
;
bool
AddFD
(
int
_fd
,
unsigned
flags
,
Socket
Monitor
&
m
)
noexcept
{
bool
AddFD
(
int
_fd
,
unsigned
flags
,
Socket
Event
&
m
)
noexcept
{
#ifdef HAVE_THREADED_EVENT_LOOP
assert
(
!
IsAlive
()
||
IsInside
());
#endif
...
...
@@ -198,7 +196,7 @@ public:
return
poll_group
.
Add
(
_fd
,
flags
,
&
m
);
}
bool
ModifyFD
(
int
_fd
,
unsigned
flags
,
Socket
Monitor
&
m
)
noexcept
{
bool
ModifyFD
(
int
_fd
,
unsigned
flags
,
Socket
Event
&
m
)
noexcept
{
#ifdef HAVE_THREADED_EVENT_LOOP
assert
(
!
IsAlive
()
||
IsInside
());
#endif
...
...
@@ -207,7 +205,7 @@ public:
}
/**
* Remove the given #Socket
Monitor
after the file descriptor
* Remove the given #Socket
Event
after the file descriptor
* has been closed. This is like RemoveFD(), but does not
* attempt to use #EPOLL_CTL_DEL.
*/
...
...
@@ -261,7 +259,7 @@ private:
Event
::
Duration
HandleTimers
()
noexcept
;
#ifdef HAVE_THREADED_EVENT_LOOP
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
#endif
public
:
...
...
src/event/MultiSocketMonitor.hxx
View file @
5a4055fb
...
...
@@ -22,7 +22,7 @@
#include "IdleEvent.hxx"
#include "TimerEvent.hxx"
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "event/Features.h"
#include <cassert>
...
...
@@ -36,35 +36,43 @@ struct pollfd;
class
EventLoop
;
/**
* Similar to #Socket
Monitor
, but monitors multiple sockets. To use
* Similar to #Socket
Event
, but monitors multiple sockets. To use
* it, implement the methods PrepareSockets() and DispatchSockets().
* In PrepareSockets(), use UpdateSocketList() and AddSocket().
* DispatchSockets() will be called if at least one socket is ready.
*/
class
MultiSocketMonitor
{
class
SingleFD
final
:
public
SocketMonitor
{
class
SingleFD
final
{
MultiSocketMonitor
&
multi
;
SocketEvent
event
;
unsigned
revents
;
public
:
SingleFD
(
MultiSocketMonitor
&
_multi
,
SocketDescriptor
_fd
)
noexcept
:
SocketMonitor
(
_fd
,
_multi
.
GetEventLoop
()),
multi
(
_multi
),
revents
(
0
)
{}
:
multi
(
_multi
),
event
(
multi
.
GetEventLoop
(),
BIND_THIS_METHOD
(
OnSocketReady
),
_fd
),
revents
(
0
)
{}
SocketDescriptor
GetSocket
()
const
noexcept
{
return
SocketMonitor
::
GetSocket
();
return
event
.
GetSocket
();
}
unsigned
GetEvents
()
const
noexcept
{
return
SocketMonitor
::
GetScheduledFlags
();
return
event
.
GetScheduledFlags
();
}
void
SetEvents
(
unsigned
_events
)
noexcept
{
revents
&=
_events
;
SocketMonitor
::
Schedule
(
_events
);
event
.
Schedule
(
_events
);
}
bool
Schedule
(
unsigned
events
)
noexcept
{
return
event
.
Schedule
(
events
);
}
unsigned
GetReturnedEvents
()
const
noexcept
{
...
...
@@ -75,11 +83,10 @@ class MultiSocketMonitor
revents
=
0
;
}
pr
otected
:
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
{
pr
ivate
:
void
OnSocketReady
(
unsigned
flags
)
noexcept
{
revents
=
flags
;
multi
.
SetReady
();
return
true
;
}
};
...
...
@@ -119,11 +126,6 @@ class MultiSocketMonitor
#endif
public
:
static
constexpr
unsigned
READ
=
SocketMonitor
::
READ
;
static
constexpr
unsigned
WRITE
=
SocketMonitor
::
WRITE
;
static
constexpr
unsigned
ERROR
=
SocketMonitor
::
ERROR
;
static
constexpr
unsigned
HANGUP
=
SocketMonitor
::
HANGUP
;
MultiSocketMonitor
(
EventLoop
&
_loop
)
noexcept
;
EventLoop
&
GetEventLoop
()
const
noexcept
{
...
...
src/event/ServerSocket.cxx
View file @
5a4055fb
...
...
@@ -29,7 +29,7 @@
#include "net/Resolver.hxx"
#include "net/AddressInfo.hxx"
#include "net/ToString.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
...
...
@@ -43,9 +43,11 @@
#include <sys/stat.h>
#endif
class
ServerSocket
::
OneServerSocket
final
:
private
SocketMonitor
{
class
ServerSocket
::
OneServerSocket
final
{
ServerSocket
&
parent
;
SocketEvent
event
;
const
unsigned
serial
;
#ifdef HAVE_UN
...
...
@@ -59,8 +61,9 @@ public:
OneServerSocket
(
EventLoop
&
_loop
,
ServerSocket
&
_parent
,
unsigned
_serial
,
A
&&
_address
)
noexcept
:
SocketMonitor
(
_loop
),
parent
(
_parent
),
serial
(
_serial
),
:
parent
(
_parent
),
event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
)),
serial
(
_serial
),
#ifdef HAVE_UN
path
(
nullptr
),
#endif
...
...
@@ -88,10 +91,15 @@ public:
}
#endif
bool
IsDefined
()
const
noexcept
{
return
event
.
IsDefined
();
}
void
Open
();
using
SocketMonitor
::
IsDefined
;
using
SocketMonitor
::
Close
;
void
Close
()
noexcept
{
event
.
Close
();
}
[[
nodiscard
]]
gcc_pure
std
::
string
ToString
()
const
noexcept
{
...
...
@@ -99,14 +107,14 @@ public:
}
void
SetFD
(
UniqueSocketDescriptor
_fd
)
noexcept
{
SocketMonitor
::
Open
(
_fd
.
Release
());
SocketMonitor
::
ScheduleRead
();
event
.
Open
(
_fd
.
Release
());
event
.
ScheduleRead
();
}
void
Accept
()
noexcept
;
private
:
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
};
static
constexpr
Domain
server_socket_domain
(
"server_socket"
);
...
...
@@ -140,7 +148,7 @@ inline void
ServerSocket
::
OneServerSocket
::
Accept
()
noexcept
{
StaticSocketAddress
peer_address
;
UniqueSocketDescriptor
peer_fd
(
GetSocket
().
AcceptNonBlock
(
peer_address
));
UniqueSocketDescriptor
peer_fd
(
event
.
GetSocket
().
AcceptNonBlock
(
peer_address
));
if
(
!
peer_fd
.
IsDefined
())
{
const
SocketErrorMessage
msg
;
FormatError
(
server_socket_domain
,
...
...
@@ -160,11 +168,10 @@ ServerSocket::OneServerSocket::Accept() noexcept
parent
.
OnAccept
(
std
::
move
(
peer_fd
),
peer_address
,
uid
);
}
bool
void
ServerSocket
::
OneServerSocket
::
OnSocketReady
([[
maybe_unused
]]
unsigned
flags
)
noexcept
{
Accept
();
return
true
;
}
inline
void
...
...
src/event/SignalMonitor.cxx
View file @
5a4055fb
...
...
@@ -22,7 +22,7 @@
#ifndef _WIN32
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "util/Manual.hxx"
#include "system/Error.hxx"
...
...
@@ -44,33 +44,37 @@
#include <pthread.h>
#endif
class
SignalMonitor
final
:
private
SocketMonitor
{
class
SignalMonitor
final
{
#ifdef USE_SIGNALFD
SignalFD
fd
;
#else
WakeFD
fd
;
#endif
SocketEvent
event
;
public
:
explicit
SignalMonitor
(
EventLoop
&
_loop
)
:
SocketMonitor
(
_loop
)
{
:
event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
)
)
{
#ifndef USE_SIGNALFD
SocketMonitor
::
Open
(
SocketDescriptor
(
fd
.
Get
()));
SocketMonitor
::
ScheduleRead
();
event
.
Open
(
SocketDescriptor
(
fd
.
Get
()));
event
.
ScheduleRead
();
#endif
}
using
SocketMonitor
::
GetEventLoop
;
auto
&
GetEventLoop
()
const
noexcept
{
return
event
.
GetEventLoop
();
}
#ifdef USE_SIGNALFD
void
Update
(
sigset_t
&
mask
)
noexcept
{
const
bool
was_open
=
SocketMonitor
::
IsDefined
();
const
bool
was_open
=
event
.
IsDefined
();
fd
.
Create
(
mask
);
if
(
!
was_open
)
{
SocketMonitor
::
Open
(
SocketDescriptor
(
fd
.
Get
()));
SocketMonitor
::
ScheduleRead
();
event
.
Open
(
SocketDescriptor
(
fd
.
Get
()));
event
.
ScheduleRead
();
}
}
#else
...
...
@@ -80,7 +84,7 @@ public:
#endif
private
:
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
};
/* this should be enough - is it? */
...
...
@@ -195,7 +199,7 @@ SignalMonitorRegister(int signo, SignalHandler handler)
#endif
}
bool
void
SignalMonitor
::
OnSocketReady
(
unsigned
)
noexcept
{
#ifdef USE_SIGNALFD
...
...
@@ -213,8 +217,6 @@ SignalMonitor::OnSocketReady(unsigned) noexcept
if
(
signal_pending
[
i
].
exchange
(
false
))
signal_handlers
[
i
]();
#endif
return
true
;
}
#endif
src/event/Socket
Monitor
.cxx
→
src/event/Socket
Event
.cxx
View file @
5a4055fb
...
...
@@ -17,7 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "Loop.hxx"
#include "event/Features.h"
...
...
@@ -29,23 +29,23 @@
#endif
void
Socket
Monitor
::
Dispatch
()
noexcept
Socket
Event
::
Dispatch
()
noexcept
{
const
unsigned
flags
=
std
::
exchange
(
ready_flags
,
0
)
&
(
GetScheduledFlags
()
|
IMPLICIT_FLAGS
);
if
(
flags
!=
0
)
OnSocketReady
(
flags
);
callback
(
flags
);
}
Socket
Monitor
::~
SocketMonitor
()
noexcept
Socket
Event
::~
SocketEvent
()
noexcept
{
if
(
IsDefined
())
Cancel
();
}
void
Socket
Monitor
::
Open
(
SocketDescriptor
_fd
)
noexcept
Socket
Event
::
Open
(
SocketDescriptor
_fd
)
noexcept
{
assert
(
!
fd
.
IsDefined
());
assert
(
_fd
.
IsDefined
());
...
...
@@ -54,7 +54,7 @@ SocketMonitor::Open(SocketDescriptor _fd) noexcept
}
SocketDescriptor
Socket
Monitor
::
Steal
()
noexcept
Socket
Event
::
Steal
()
noexcept
{
assert
(
IsDefined
());
...
...
@@ -64,13 +64,13 @@ SocketMonitor::Steal() noexcept
}
void
Socket
Monitor
::
Close
()
noexcept
Socket
Event
::
Close
()
noexcept
{
Steal
().
Close
();
}
bool
Socket
Monitor
::
Schedule
(
unsigned
flags
)
noexcept
Socket
Event
::
Schedule
(
unsigned
flags
)
noexcept
{
assert
(
IsDefined
());
...
...
src/event/Socket
Monitor
.hxx
→
src/event/Socket
Event
.hxx
View file @
5a4055fb
...
...
@@ -17,11 +17,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_SOCKET_
MONITOR
_HXX
#define MPD_SOCKET_
MONITOR
_HXX
#ifndef MPD_SOCKET_
EVENT
_HXX
#define MPD_SOCKET_
EVENT
_HXX
#include "PollGroup.hxx"
#include "net/SocketDescriptor.hxx"
#include "util/BindMethod.hxx"
#include <boost/intrusive/list_hook.hpp>
...
...
@@ -34,8 +35,8 @@ class EventLoop;
/**
* Monitor events on a socket. Call Schedule() to announce events
* you're interested in, or Cancel() to cancel your subscription. The
* #EventLoop will invoke
virtual method OnSocketReady() as soon as
*
any of the
subscribed events are ready.
* #EventLoop will invoke
the callback as soon as any of the
* subscribed events are ready.
*
* This class does not feel responsible for closing the socket. Call
* Close() to do it manually.
...
...
@@ -44,14 +45,18 @@ class EventLoop;
* thread that runs the #EventLoop, except where explicitly documented
* as thread-safe.
*/
class
Socket
Monitor
{
class
Socket
Event
{
friend
class
EventLoop
;
EventLoop
&
loop
;
using
ReadyListHook
=
boost
::
intrusive
::
list_member_hook
<
boost
::
intrusive
::
link_mode
<
boost
::
intrusive
::
auto_unlink
>>
;
ReadyListHook
ready_siblings
;
using
Callback
=
BoundMethod
<
void
(
unsigned
events
)
noexcept
>
;
const
Callback
callback
;
SocketDescriptor
fd
=
SocketDescriptor
::
Undefined
();
EventLoop
&
loop
;
/**
* A bit mask of events that is currently registered in the
...
...
@@ -80,13 +85,13 @@ public:
typedef
std
::
make_signed
<
size_t
>::
type
ssize_t
;
explicit
SocketMonitor
(
EventLoop
&
_loop
)
noexcept
:
loop
(
_loop
)
{}
SocketEvent
(
EventLoop
&
_loop
,
Callback
_callback
,
SocketDescriptor
_fd
=
SocketDescriptor
::
Undefined
())
noexcept
:
loop
(
_loop
),
callback
(
_callback
),
fd
(
_fd
)
{}
SocketMonitor
(
SocketDescriptor
_fd
,
EventLoop
&
_loop
)
noexcept
:
fd
(
_fd
),
loop
(
_loop
)
{}
~
SocketMonitor
()
noexcept
;
~
SocketEvent
()
noexcept
;
auto
&
GetEventLoop
()
const
noexcept
{
return
loop
;
...
...
@@ -148,12 +153,6 @@ public:
Schedule
(
GetScheduledFlags
()
&
~
WRITE
);
}
protected
:
/**
* @return false if the socket has been closed
*/
virtual
bool
OnSocketReady
(
unsigned
flags
)
noexcept
=
0
;
public
:
void
Dispatch
()
noexcept
;
};
...
...
src/event/UringManager.cxx
View file @
5a4055fb
...
...
@@ -22,15 +22,13 @@
namespace
Uring
{
bool
void
Manager
::
OnSocketReady
(
unsigned
)
noexcept
{
try
{
DispatchCompletions
();
return
true
;
}
catch
(...)
{
PrintException
(
std
::
current_exception
());
return
false
;
}
}
...
...
src/event/UringManager.hxx
View file @
5a4055fb
...
...
@@ -19,23 +19,24 @@
#pragma once
#include "Socket
Monitor
.hxx"
#include "Socket
Event
.hxx"
#include "IdleEvent.hxx"
#include "io/uring/Queue.hxx"
namespace
Uring
{
class
Manager
final
:
public
Queue
,
SocketMonitor
{
class
Manager
final
:
public
Queue
{
SocketEvent
event
;
IdleEvent
idle_event
;
public
:
explicit
Manager
(
EventLoop
&
event_loop
)
:
Queue
(
1024
,
0
),
SocketMonitor
(
SocketDescriptor
::
FromFileDescriptor
(
GetFileDescriptor
()
),
event_loop
),
event
(
event_loop
,
BIND_THIS_METHOD
(
OnSocketReady
),
SocketDescriptor
::
FromFileDescriptor
(
GetFileDescriptor
())
),
idle_event
(
event_loop
,
BIND_THIS_METHOD
(
OnIdle
))
{
SocketMonitor
::
ScheduleRead
();
event
.
ScheduleRead
();
}
void
Push
(
struct
io_uring_sqe
&
sqe
,
...
...
@@ -45,7 +46,7 @@ public:
}
private
:
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
void
OnIdle
()
noexcept
;
};
...
...
src/event/meson.build
View file @
5a4055fb
...
...
@@ -26,7 +26,7 @@ event = static_library(
'IdleEvent.cxx',
'DeferEvent.cxx',
'MaskMonitor.cxx',
'Socket
Monitor
.cxx',
'Socket
Event
.cxx',
'BufferedSocket.cxx',
'FullyBufferedSocket.cxx',
'MultiSocketMonitor.cxx',
...
...
src/lib/curl/Global.cxx
View file @
5a4055fb
...
...
@@ -31,7 +31,7 @@
#include "Request.hxx"
#include "Log.hxx"
#include "event/Loop.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
...
...
@@ -42,12 +42,15 @@ static constexpr Domain curlm_domain("curlm");
/**
* Monitor for one socket created by CURL.
*/
class
CurlSocket
final
:
SocketMonitor
{
class
CurlSocket
final
{
CurlGlobal
&
global
;
SocketEvent
socket_event
;
public
:
CurlSocket
(
CurlGlobal
&
_global
,
EventLoop
&
_loop
,
SocketDescriptor
_fd
)
:
SocketMonitor
(
_fd
,
_loop
),
global
(
_global
)
{}
:
global
(
_global
),
socket_event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
),
_fd
)
{}
~
CurlSocket
()
noexcept
{
/* TODO: sometimes, CURL uses CURL_POLL_REMOVE after
...
...
@@ -59,6 +62,10 @@ public:
better solution? */
}
auto
&
GetEventLoop
()
const
noexcept
{
return
socket_event
.
GetEventLoop
();
}
/**
* Callback function for CURLMOPT_SOCKETFUNCTION.
*/
...
...
@@ -66,13 +73,17 @@ public:
curl_socket_t
s
,
int
action
,
void
*
userp
,
void
*
socketp
)
noexcept
;
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
private
:
SocketDescriptor
GetSocket
()
const
noexcept
{
return
socket_event
.
GetSocket
();
}
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
static
constexpr
int
FlagsToCurlCSelect
(
unsigned
flags
)
noexcept
{
return
(
flags
&
(
READ
|
HANGUP
)
?
CURL_CSELECT_IN
:
0
)
|
(
flags
&
WRITE
?
CURL_CSELECT_OUT
:
0
)
|
(
flags
&
ERROR
?
CURL_CSELECT_ERR
:
0
);
return
(
flags
&
(
SocketEvent
::
READ
|
SocketEvent
::
HANGUP
)
?
CURL_CSELECT_IN
:
0
)
|
(
flags
&
SocketEvent
::
WRITE
?
CURL_CSELECT_OUT
:
0
)
|
(
flags
&
SocketEvent
::
ERROR
?
CURL_CSELECT_ERR
:
0
);
}
gcc_const
...
...
@@ -82,13 +93,13 @@ private:
return
0
;
case
CURL_POLL_IN
:
return
READ
;
return
SocketEvent
::
READ
;
case
CURL_POLL_OUT
:
return
WRITE
;
return
SocketEvent
::
WRITE
;
case
CURL_POLL_INOUT
:
return
READ
|
WRITE
;
return
SocketEvent
::
READ
|
SocketEvent
::
WRITE
;
}
assert
(
false
);
...
...
@@ -130,17 +141,16 @@ CurlSocket::SocketFunction([[maybe_unused]] CURL *easy,
unsigned
flags
=
CurlPollToFlags
(
action
);
if
(
flags
!=
0
)
cs
->
Schedule
(
flags
);
cs
->
socket_event
.
Schedule
(
flags
);
return
0
;
}
bool
void
CurlSocket
::
OnSocketReady
(
unsigned
flags
)
noexcept
{
assert
(
GetEventLoop
().
IsInside
());
global
.
SocketAction
(
GetSocket
().
Get
(),
FlagsToCurlCSelect
(
flags
));
return
true
;
}
void
...
...
src/lib/dbus/Watch.cxx
View file @
5a4055fb
/*
* Copyright 2007-20
18 Content Management AG
* Copyright 2007-20
20 CM4all GmbH
* All rights reserved.
*
* author: Max Kellermann <mk@cm4all.com>
...
...
@@ -36,8 +36,8 @@ namespace ODBus {
WatchManager
::
Watch
::
Watch
(
EventLoop
&
event_loop
,
WatchManager
&
_parent
,
DBusWatch
&
_watch
)
noexcept
:
SocketMonitor
(
event_loop
),
parent
(
_parent
),
watch
(
_watch
)
:
parent
(
_parent
),
watch
(
_watch
),
event
(
event_loop
,
BIND_THIS_METHOD
(
OnSocketReady
)
)
{
Toggled
();
}
...
...
@@ -45,30 +45,30 @@ WatchManager::Watch::Watch(EventLoop &event_loop,
static
constexpr
unsigned
DbusToLibevent
(
unsigned
flags
)
noexcept
{
return
((
flags
&
DBUS_WATCH_READABLE
)
!=
0
)
*
Socket
Monitor
::
READ
|
((
flags
&
DBUS_WATCH_WRITABLE
)
!=
0
)
*
Socket
Monitor
::
WRITE
;
return
((
flags
&
DBUS_WATCH_READABLE
)
!=
0
)
*
Socket
Event
::
READ
|
((
flags
&
DBUS_WATCH_WRITABLE
)
!=
0
)
*
Socket
Event
::
WRITE
;
}
void
WatchManager
::
Watch
::
Toggled
()
noexcept
{
if
(
SocketMonitor
::
IsDefined
())
SocketMonitor
::
Cancel
();
if
(
event
.
IsDefined
())
event
.
Cancel
();
if
(
dbus_watch_get_enabled
(
&
watch
))
{
SocketMonitor
::
Open
(
SocketDescriptor
(
dbus_watch_get_unix_fd
(
&
watch
)));
SocketMonitor
::
Schedule
(
DbusToLibevent
(
dbus_watch_get_flags
(
&
watch
)));
event
.
Open
(
SocketDescriptor
(
dbus_watch_get_unix_fd
(
&
watch
)));
event
.
Schedule
(
DbusToLibevent
(
dbus_watch_get_flags
(
&
watch
)));
}
}
static
constexpr
unsigned
LibeventToDbus
(
unsigned
flags
)
noexcept
{
return
((
flags
&
Socket
Monitor
::
READ
)
!=
0
)
*
DBUS_WATCH_READABLE
|
((
flags
&
Socket
Monitor
::
WRITE
)
!=
0
)
*
DBUS_WATCH_WRITABLE
;
return
((
flags
&
Socket
Event
::
READ
)
!=
0
)
*
DBUS_WATCH_READABLE
|
((
flags
&
Socket
Event
::
WRITE
)
!=
0
)
*
DBUS_WATCH_WRITABLE
;
}
bool
void
WatchManager
::
Watch
::
OnSocketReady
(
unsigned
events
)
noexcept
{
/* copy the "parent" reference to the stack, because the
...
...
@@ -79,7 +79,6 @@ WatchManager::Watch::OnSocketReady(unsigned events) noexcept
dbus_watch_handle
(
&
watch
,
LibeventToDbus
(
events
));
_parent
.
ScheduleDispatch
();
return
true
;
}
void
...
...
src/lib/dbus/Watch.hxx
View file @
5a4055fb
/*
* Copyright 2007-20
18 Content Management AG
* Copyright 2007-20
20 CM4all GmbH
* All rights reserved.
*
* author: Max Kellermann <mk@cm4all.com>
...
...
@@ -34,7 +34,7 @@
#define ODBUS_WATCH_HXX
#include "Connection.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "event/DeferEvent.hxx"
#include <dbus/dbus.h>
...
...
@@ -58,9 +58,10 @@ class WatchManager {
Connection
connection
;
class
Watch
final
:
SocketMonitor
{
class
Watch
{
WatchManager
&
parent
;
DBusWatch
&
watch
;
SocketEvent
event
;
public
:
Watch
(
EventLoop
&
event_loop
,
WatchManager
&
_parent
,
...
...
@@ -69,7 +70,7 @@ class WatchManager {
void
Toggled
()
noexcept
;
private
:
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
};
std
::
map
<
DBusWatch
*
,
Watch
>
watches
;
...
...
src/lib/nfs/Connection.cxx
View file @
5a4055fb
...
...
@@ -183,17 +183,17 @@ NfsConnection::CancellableCallback::Callback(int err,
static
constexpr
unsigned
libnfs_to_events
(
int
i
)
noexcept
{
return
((
i
&
POLLIN
)
?
Socket
Monitor
::
READ
:
0
)
|
((
i
&
POLLOUT
)
?
Socket
Monitor
::
WRITE
:
0
);
return
((
i
&
POLLIN
)
?
Socket
Event
::
READ
:
0
)
|
((
i
&
POLLOUT
)
?
Socket
Event
::
WRITE
:
0
);
}
static
constexpr
int
events_to_libnfs
(
unsigned
i
)
noexcept
{
return
((
i
&
Socket
Monitor
::
READ
)
?
POLLIN
:
0
)
|
((
i
&
Socket
Monitor
::
WRITE
)
?
POLLOUT
:
0
)
|
((
i
&
Socket
Monitor
::
HANGUP
)
?
POLLHUP
:
0
)
|
((
i
&
Socket
Monitor
::
ERROR
)
?
POLLERR
:
0
);
return
((
i
&
Socket
Event
::
READ
)
?
POLLIN
:
0
)
|
((
i
&
Socket
Event
::
WRITE
)
?
POLLOUT
:
0
)
|
((
i
&
Socket
Event
::
HANGUP
)
?
POLLHUP
:
0
)
|
((
i
&
Socket
Event
::
ERROR
)
?
POLLERR
:
0
);
}
NfsConnection
::~
NfsConnection
()
noexcept
...
...
@@ -403,8 +403,8 @@ NfsConnection::DestroyContext() noexcept
new leases */
defer_new_lease
.
Cancel
();
if
(
SocketMonitor
::
IsDefined
())
SocketMonitor
::
Steal
();
if
(
socket_event
.
IsDefined
())
socket_event
.
Steal
();
callbacks
.
ForEach
([](
CancellableCallback
&
c
){
c
.
PrepareDestroyContext
();
...
...
@@ -434,25 +434,25 @@ NfsConnection::ScheduleSocket() noexcept
const
int
which_events
=
nfs_which_events
(
context
);
if
(
which_events
==
POLLOUT
&&
SocketMonitor
::
IsDefined
())
if
(
which_events
==
POLLOUT
&&
socket_event
.
IsDefined
())
/* kludge: if libnfs asks only for POLLOUT, it means
that it is currently waiting for the connect() to
finish - rpc_reconnect_requeue() may have been
called from inside nfs_service(); we must now
unregister the old socket and register the new one
instead */
SocketMonitor
::
Steal
();
socket_event
.
Steal
();
if
(
!
SocketMonitor
::
IsDefined
())
{
if
(
!
socket_event
.
IsDefined
())
{
SocketDescriptor
_fd
(
nfs_get_fd
(
context
));
if
(
!
_fd
.
IsDefined
())
return
;
_fd
.
EnableCloseOnExec
();
SocketMonitor
::
Open
(
_fd
);
socket_event
.
Open
(
_fd
);
}
SocketMonitor
::
Schedule
(
libnfs_to_events
(
which_events
));
socket_event
.
Schedule
(
libnfs_to_events
(
which_events
));
}
inline
int
...
...
@@ -480,16 +480,14 @@ NfsConnection::Service(unsigned flags) noexcept
return
result
;
}
bool
void
NfsConnection
::
OnSocketReady
(
unsigned
flags
)
noexcept
{
assert
(
GetEventLoop
().
IsInside
());
assert
(
deferred_close
.
empty
());
bool
closed
=
false
;
const
bool
was_mounted
=
mount_finished
;
if
(
!
mount_finished
||
(
flags
&
Socket
Monitor
::
HANGUP
)
!=
0
)
if
(
!
mount_finished
||
(
flags
&
Socket
Event
::
HANGUP
)
!=
0
)
/* until the mount is finished, the NFS client may use
various sockets, therefore we unregister and
re-register it each time */
...
...
@@ -497,7 +495,7 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
which is a sure sign that libnfs will close the
socket, which can lead to a race condition if
epoll_ctl() is called later */
SocketMonitor
::
Steal
();
socket_event
.
Steal
();
const
int
result
=
Service
(
flags
);
...
...
@@ -509,7 +507,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
if
(
!
was_mounted
&&
mount_finished
)
{
if
(
postponed_mount_error
)
{
DestroyContext
();
closed
=
true
;
BroadcastMountError
(
std
::
move
(
postponed_mount_error
));
}
else
if
(
result
==
0
)
BroadcastMountSuccess
();
...
...
@@ -521,7 +518,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
BroadcastError
(
std
::
make_exception_ptr
(
e
));
DestroyContext
();
closed
=
true
;
}
else
if
(
nfs_get_fd
(
context
)
<
0
)
{
/* this happens when rpc_reconnect_requeue() is called
after the connection broke, but autoreconnect was
...
...
@@ -535,7 +531,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
BroadcastError
(
std
::
make_exception_ptr
(
e
));
DestroyContext
();
closed
=
true
;
}
assert
(
context
==
nullptr
||
nfs_get_fd
(
context
)
>=
0
);
...
...
@@ -547,8 +542,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept
if
(
context
!=
nullptr
)
ScheduleSocket
();
return
!
closed
;
}
inline
void
...
...
src/lib/nfs/Connection.hxx
View file @
5a4055fb
...
...
@@ -21,7 +21,7 @@
#define MPD_NFS_CONNECTION_HXX
#include "Cancellable.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "event/TimerEvent.hxx"
#include "event/DeferEvent.hxx"
#include "util/Compiler.h"
...
...
@@ -40,7 +40,7 @@ class NfsLease;
/**
* An asynchronous connection to a NFS server.
*/
class
NfsConnection
:
SocketMonitor
{
class
NfsConnection
{
class
CancellableCallback
:
public
CancellablePointer
<
NfsCallback
>
{
NfsConnection
&
connection
;
...
...
@@ -93,6 +93,7 @@ class NfsConnection : SocketMonitor {
void
Callback
(
int
err
,
void
*
data
)
noexcept
;
};
SocketEvent
socket_event
;
DeferEvent
defer_new_lease
;
TimerEvent
mount_timeout_event
;
...
...
@@ -141,7 +142,7 @@ public:
gcc_nonnull_all
NfsConnection
(
EventLoop
&
_loop
,
const
char
*
_server
,
const
char
*
_export_name
)
noexcept
:
SocketMonitor
(
_loop
),
:
socket_event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
)
),
defer_new_lease
(
_loop
,
BIND_THIS_METHOD
(
RunDeferred
)),
mount_timeout_event
(
_loop
,
BIND_THIS_METHOD
(
OnMountTimeout
)),
server
(
_server
),
export_name
(
_export_name
),
...
...
@@ -152,6 +153,10 @@ public:
*/
~
NfsConnection
()
noexcept
;
auto
&
GetEventLoop
()
const
noexcept
{
return
socket_event
.
GetEventLoop
();
}
gcc_pure
const
char
*
GetServer
()
const
noexcept
{
return
server
.
c_str
();
...
...
@@ -162,8 +167,6 @@ public:
return
export_name
.
c_str
();
}
using
SocketMonitor
::
GetEventLoop
;
/**
* Ensure that the connection is established. The connection
* is kept up while at least one #NfsLease is registered.
...
...
@@ -231,8 +234,7 @@ private:
*/
int
Service
(
unsigned
flags
)
noexcept
;
/* virtual methods from SocketMonitor */
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
void
OnSocketReady
(
unsigned
flags
)
noexcept
;
/* callback for #mount_timeout_event */
void
OnMountTimeout
()
noexcept
;
...
...
src/output/plugins/httpd/HttpdClient.cxx
View file @
5a4055fb
...
...
@@ -216,7 +216,7 @@ HttpdClient::CancelQueue() noexcept
ClearQueue
();
if
(
current_page
==
nullptr
)
CancelWrite
();
event
.
CancelWrite
();
}
ssize_t
...
...
@@ -259,7 +259,7 @@ HttpdClient::TryWrite() noexcept
/* another thread has removed the event source
while this thread was waiting for
httpd.mutex */
CancelWrite
();
event
.
CancelWrite
();
return
true
;
}
...
...
@@ -354,7 +354,7 @@ HttpdClient::TryWrite() noexcept
if
(
pages
.
empty
())
/* all pages are sent: remove the
event source */
CancelWrite
();
event
.
CancelWrite
();
}
}
...
...
@@ -377,7 +377,7 @@ HttpdClient::PushPage(PagePtr page) noexcept
queue_size
+=
page
->
GetSize
();
pages
.
emplace
(
std
::
move
(
page
));
ScheduleWrite
();
event
.
ScheduleWrite
();
}
void
...
...
@@ -389,17 +389,14 @@ HttpdClient::PushMetaData(PagePtr page) noexcept
metadata_sent
=
false
;
}
bool
void
HttpdClient
::
OnSocketReady
(
unsigned
flags
)
noexcept
{
if
(
!
BufferedSocket
::
OnSocketReady
(
flags
))
return
false
;
if
(
flags
&
WRITE
)
if
(
flags
&
SocketEvent
::
WRITE
)
if
(
!
TryWrite
())
return
false
;
return
;
return
true
;
BufferedSocket
::
OnSocketReady
(
flags
)
;
}
BufferedSocket
::
InputResult
...
...
src/output/plugins/httpd/HttpdClient.hxx
View file @
5a4055fb
...
...
@@ -196,8 +196,8 @@ private:
void
ClearQueue
()
noexcept
;
protected
:
/* virtual methods from class
SocketMonitor
*/
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
/* virtual methods from class
BufferedSocket
*/
void
OnSocketReady
(
unsigned
flags
)
noexcept
override
;
InputResult
OnSocketInput
(
void
*
data
,
size_t
length
)
noexcept
override
;
void
OnSocketError
(
std
::
exception_ptr
ep
)
noexcept
override
;
...
...
src/zeroconf/AvahiPoll.cxx
View file @
5a4055fb
...
...
@@ -18,28 +18,29 @@
*/
#include "AvahiPoll.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "event/TimerEvent.hxx"
#include "time/Convert.hxx"
static
unsigned
FromAvahiWatchEvent
(
AvahiWatchEvent
e
)
{
return
(
e
&
AVAHI_WATCH_IN
?
Socket
Monitor
::
READ
:
0
)
|
(
e
&
AVAHI_WATCH_OUT
?
Socket
Monitor
::
WRITE
:
0
);
return
(
e
&
AVAHI_WATCH_IN
?
Socket
Event
::
READ
:
0
)
|
(
e
&
AVAHI_WATCH_OUT
?
Socket
Event
::
WRITE
:
0
);
}
static
AvahiWatchEvent
ToAvahiWatchEvent
(
unsigned
e
)
{
return
AvahiWatchEvent
((
e
&
Socket
Monitor
::
READ
?
AVAHI_WATCH_IN
:
0
)
|
(
e
&
Socket
Monitor
::
WRITE
?
AVAHI_WATCH_OUT
:
0
)
|
(
e
&
Socket
Monitor
::
ERROR
?
AVAHI_WATCH_ERR
:
0
)
|
(
e
&
Socket
Monitor
::
HANGUP
?
AVAHI_WATCH_HUP
:
0
));
return
AvahiWatchEvent
((
e
&
Socket
Event
::
READ
?
AVAHI_WATCH_IN
:
0
)
|
(
e
&
Socket
Event
::
WRITE
?
AVAHI_WATCH_OUT
:
0
)
|
(
e
&
Socket
Event
::
ERROR
?
AVAHI_WATCH_ERR
:
0
)
|
(
e
&
Socket
Event
::
HANGUP
?
AVAHI_WATCH_HUP
:
0
));
}
struct
AvahiWatch
final
:
private
SocketMonitor
{
private
:
struct
AvahiWatch
final
{
SocketEvent
event
;
const
AvahiWatchCallback
callback
;
void
*
const
userdata
;
...
...
@@ -49,14 +50,14 @@ public:
AvahiWatch
(
SocketDescriptor
_fd
,
AvahiWatchEvent
_event
,
AvahiWatchCallback
_callback
,
void
*
_userdata
,
EventLoop
&
_loop
)
:
SocketMonitor
(
_fd
,
_loop
),
:
event
(
_loop
,
BIND_THIS_METHOD
(
OnSocketReady
),
_fd
),
callback
(
_callback
),
userdata
(
_userdata
),
received
(
AvahiWatchEvent
(
0
))
{
Schedule
(
FromAvahiWatchEvent
(
_event
));
event
.
Schedule
(
FromAvahiWatchEvent
(
_event
));
}
static
void
WatchUpdate
(
AvahiWatch
*
w
,
AvahiWatchEvent
event
)
{
w
->
Schedule
(
FromAvahiWatchEvent
(
event
));
w
->
event
.
Schedule
(
FromAvahiWatchEvent
(
event
));
}
static
AvahiWatchEvent
WatchGetEvents
(
AvahiWatch
*
w
)
{
...
...
@@ -68,12 +69,10 @@ public:
}
private
:
/* virtual methods from class SocketMonitor */
bool
OnSocketReady
(
unsigned
flags
)
noexcept
override
{
void
OnSocketReady
(
unsigned
flags
)
noexcept
{
received
=
ToAvahiWatchEvent
(
flags
);
callback
(
this
,
GetSocket
().
Get
(),
received
,
userdata
);
callback
(
this
,
event
.
GetSocket
().
Get
(),
received
,
userdata
);
received
=
AvahiWatchEvent
(
0
);
return
true
;
}
};
...
...
src/zeroconf/ZeroconfBonjour.cxx
View file @
5a4055fb
...
...
@@ -20,7 +20,7 @@
#include "ZeroconfBonjour.hxx"
#include "ZeroconfInternal.hxx"
#include "Listen.hxx"
#include "event/Socket
Monitor
.hxx"
#include "event/Socket
Event
.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
#include "util/Compiler.h"
...
...
@@ -31,15 +31,19 @@
static
constexpr
Domain
bonjour_domain
(
"bonjour"
);
class
BonjourMonitor
final
:
public
SocketMonitor
{
class
BonjourMonitor
final
{
DNSServiceRef
service_ref
;
SocketEvent
socket_event
;
public
:
BonjourMonitor
(
EventLoop
&
_loop
,
DNSServiceRef
_service_ref
)
:
SocketMonitor
(
SocketDescriptor
(
DNSServiceRefSockFD
(
_service_ref
)),
_loop
),
service_ref
(
_service_ref
)
{
ScheduleRead
();
:
service_ref
(
_service_ref
),
socket_event
(
SocketDescriptor
(
DNSServiceRefSockFD
(
service_ref
)),
BIND_THIS_METHOD
(
OnSocketReady
),
_loop
)
{
socket_event
.
ScheduleRead
();
}
~
BonjourMonitor
()
{
...
...
@@ -48,9 +52,8 @@ public:
protected
:
/* virtual methods from class SocketMonitor */
bool
OnSocketReady
([[
maybe_unused
]]
unsigned
flags
)
noexcept
override
{
void
OnSocketReady
([[
maybe_unused
]]
unsigned
flags
)
noexcept
override
{
DNSServiceProcessResult
(
service_ref
);
return
true
;
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment