event/PipeEvent: new class wrapping SocketEvent
This commit is contained in:
		| @@ -37,7 +37,7 @@ InotifySource::OnSocketReady([[maybe_unused]] unsigned flags) noexcept | ||||
| 	static_assert(sizeof(buffer) >= sizeof(struct inotify_event) + NAME_MAX + 1, | ||||
| 		      "inotify buffer too small"); | ||||
|  | ||||
| 	auto ifd = socket_event.GetSocket().ToFileDescriptor(); | ||||
| 	auto ifd = socket_event.GetFileDescriptor(); | ||||
| 	ssize_t nbytes = ifd.Read(buffer, sizeof(buffer)); | ||||
| 	if (nbytes < 0) | ||||
| 		FatalSystemError("Failed to read from inotify"); | ||||
| @@ -78,7 +78,7 @@ InotifyInit() | ||||
| InotifySource::InotifySource(EventLoop &_loop, | ||||
| 			     mpd_inotify_callback_t _callback, void *_ctx) | ||||
| 	:socket_event(_loop, BIND_THIS_METHOD(OnSocketReady), | ||||
| 		      SocketDescriptor::FromFileDescriptor(InotifyInit())), | ||||
| 		      InotifyInit()), | ||||
| 	 callback(_callback), callback_ctx(_ctx) | ||||
| { | ||||
| 	socket_event.ScheduleRead(); | ||||
| @@ -87,7 +87,7 @@ InotifySource::InotifySource(EventLoop &_loop, | ||||
| int | ||||
| InotifySource::Add(const char *path_fs, unsigned mask) | ||||
| { | ||||
| 	auto ifd = socket_event.GetSocket().ToFileDescriptor(); | ||||
| 	auto ifd = socket_event.GetFileDescriptor(); | ||||
| 	int wd = inotify_add_watch(ifd.Get(), path_fs, mask); | ||||
| 	if (wd < 0) | ||||
| 		throw MakeErrno("inotify_add_watch() has failed"); | ||||
| @@ -98,7 +98,7 @@ InotifySource::Add(const char *path_fs, unsigned mask) | ||||
| void | ||||
| InotifySource::Remove(unsigned wd) noexcept | ||||
| { | ||||
| 	auto ifd = socket_event.GetSocket().ToFileDescriptor(); | ||||
| 	auto ifd = socket_event.GetFileDescriptor(); | ||||
| 	int ret = inotify_rm_watch(ifd.Get(), wd); | ||||
| 	if (ret < 0 && errno != EINVAL) | ||||
| 		LogErrno(inotify_domain, "inotify_rm_watch() has failed"); | ||||
|   | ||||
| @@ -20,13 +20,13 @@ | ||||
| #ifndef MPD_INOTIFY_SOURCE_HXX | ||||
| #define MPD_INOTIFY_SOURCE_HXX | ||||
|  | ||||
| #include "event/SocketEvent.hxx" | ||||
| #include "event/PipeEvent.hxx" | ||||
|  | ||||
| typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask, | ||||
| 				       const char *name, void *ctx); | ||||
|  | ||||
| class InotifySource final { | ||||
| 	SocketEvent socket_event; | ||||
| 	PipeEvent socket_event; | ||||
|  | ||||
| 	mpd_inotify_callback_t callback; | ||||
| 	void *callback_ctx; | ||||
|   | ||||
							
								
								
									
										103
									
								
								src/event/PipeEvent.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/event/PipeEvent.hxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| /* | ||||
|  * Copyright 2007-2021 CM4all GmbH | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * author: Max Kellermann <mk@cm4all.com> | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * | ||||
|  * - Redistributions of source code must retain the above copyright | ||||
|  * notice, this list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * - Redistributions in binary form must reproduce the above copyright | ||||
|  * notice, this list of conditions and the following disclaimer in the | ||||
|  * documentation and/or other materials provided with the | ||||
|  * distribution. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
|  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||||
|  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE | ||||
|  * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
|  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||||
|  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||||
|  * OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "SocketEvent.hxx" | ||||
| #include "io/FileDescriptor.hxx" | ||||
|  | ||||
| /** | ||||
|  * A variant of #SocketEvent for pipes (and other kinds of | ||||
|  * #FileDescriptor which can be used with epoll). | ||||
|  */ | ||||
| class PipeEvent final { | ||||
| 	SocketEvent event; | ||||
|  | ||||
| public: | ||||
| 	template<typename C> | ||||
| 	PipeEvent(EventLoop &event_loop, C callback, | ||||
| 		  FileDescriptor fd=FileDescriptor::Undefined()) noexcept | ||||
| 		:event(event_loop, callback, | ||||
| 		       SocketDescriptor::FromFileDescriptor(fd)) {} | ||||
|  | ||||
| 	EventLoop &GetEventLoop() const noexcept { | ||||
| 		return event.GetEventLoop(); | ||||
| 	} | ||||
|  | ||||
| 	bool IsDefined() const noexcept { | ||||
| 		return event.IsDefined(); | ||||
| 	} | ||||
|  | ||||
| 	FileDescriptor GetFileDescriptor() const noexcept { | ||||
| 		return event.GetSocket().ToFileDescriptor(); | ||||
| 	} | ||||
|  | ||||
| 	FileDescriptor ReleaseFileDescriptor() noexcept { | ||||
| 		return event.ReleaseSocket().ToFileDescriptor(); | ||||
| 	} | ||||
|  | ||||
| 	void Open(FileDescriptor fd) noexcept { | ||||
| 		event.Open(SocketDescriptor::FromFileDescriptor(fd)); | ||||
| 	} | ||||
|  | ||||
| 	void Close() noexcept { | ||||
| 		event.Close(); | ||||
| 	} | ||||
|  | ||||
| 	bool Schedule(unsigned flags) noexcept { | ||||
| 		return event.Schedule(flags); | ||||
| 	} | ||||
|  | ||||
| 	void Cancel() noexcept { | ||||
| 		event.Cancel(); | ||||
| 	} | ||||
|  | ||||
| 	bool ScheduleRead() noexcept { | ||||
| 		return event.ScheduleRead(); | ||||
| 	} | ||||
|  | ||||
| 	bool ScheduleWrite() noexcept { | ||||
| 		return event.ScheduleWrite(); | ||||
| 	} | ||||
|  | ||||
| 	void CancelRead() noexcept { | ||||
| 		event.CancelRead(); | ||||
| 	} | ||||
|  | ||||
| 	void CancelWrite() noexcept { | ||||
| 		event.CancelWrite(); | ||||
| 	} | ||||
|  | ||||
| 	void ScheduleImplicit() noexcept { | ||||
| 		event.ScheduleImplicit(); | ||||
| 	} | ||||
| }; | ||||
| @@ -19,21 +19,21 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "SocketEvent.hxx" | ||||
| #include "PipeEvent.hxx" | ||||
| #include "IdleEvent.hxx" | ||||
| #include "io/uring/Queue.hxx" | ||||
|  | ||||
| namespace Uring { | ||||
|  | ||||
| class Manager final : public Queue { | ||||
| 	SocketEvent event; | ||||
| 	PipeEvent event; | ||||
| 	IdleEvent idle_event; | ||||
|  | ||||
| public: | ||||
| 	explicit Manager(EventLoop &event_loop) | ||||
| 		:Queue(1024, 0), | ||||
| 		 event(event_loop, BIND_THIS_METHOD(OnSocketReady), | ||||
| 		       SocketDescriptor::FromFileDescriptor(GetFileDescriptor())), | ||||
| 		       GetFileDescriptor()), | ||||
| 		 idle_event(event_loop, BIND_THIS_METHOD(OnIdle)) | ||||
| 	{ | ||||
| 		event.ScheduleRead(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann