Skip to content

Commit

Permalink
event/Loop: explicit io_uring initialization
Browse files Browse the repository at this point in the history
Log the io_uring initialization error at MPD startup.
  • Loading branch information
MaxKellermann committed Feb 1, 2025
1 parent 63cc07b commit 00a352f
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 34 deletions.
57 changes: 32 additions & 25 deletions src/event/Loop.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

#ifdef HAVE_URING
#include "uring/Manager.hxx"
#include "util/PrintException.hxx"
#include <stdio.h>
#endif

EventLoop::EventLoop(
Expand Down Expand Up @@ -53,26 +51,46 @@ EventLoop::~EventLoop() noexcept
assert(ready_sockets.empty());
}

void
EventLoop::SetVolatile() noexcept
{
#ifdef HAVE_URING
if (uring)
uring->SetVolatile();
#endif
}

#ifdef HAVE_URING

void
EventLoop::EnableUring(unsigned entries, unsigned flags)
{
assert(!uring);

uring = std::make_unique<Uring::Manager>(*this, entries, flags);
}

void
EventLoop::EnableUring(unsigned entries, struct io_uring_params &params)
{
assert(!uring);

uring = std::make_unique<Uring::Manager>(*this, entries, params);
}

void
EventLoop::DisableUring() noexcept
{
uring.reset();
}

Uring::Queue *
EventLoop::GetUring() noexcept
{
if (!uring_initialized) {
uring_initialized = true;
try {
uring = std::make_unique<Uring::Manager>(*this, 1024,
IORING_SETUP_SINGLE_ISSUER);
} catch (...) {
fprintf(stderr, "Failed to initialize io_uring: ");
PrintException(std::current_exception());
}
}

return uring.get();
}

#endif
#endif // HAVE_URING

bool
EventLoop::AddFD(int fd, unsigned events, SocketEvent &event) noexcept
Expand Down Expand Up @@ -280,17 +298,6 @@ EventLoop::Run() noexcept
wake_event.Schedule(SocketEvent::READ);
#endif

#ifdef HAVE_URING
AtScopeExit(this) {
/* make sure that the Uring::Manager gets destructed
from within the EventThread, or else its
destruction in another thread will cause assertion
failures */
uring.reset();
uring_initialized = false;
};
#endif

#ifdef HAVE_THREADED_EVENT_LOOP
AtScopeExit(this) {
wake_event.Cancel();
Expand Down
26 changes: 21 additions & 5 deletions src/event/Loop.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "io/uring/Features.h"
#ifdef HAVE_URING
#include <memory>
struct io_uring_params;
namespace Uring { class Queue; class Manager; }
#endif

Expand Down Expand Up @@ -133,10 +134,6 @@ class EventLoop final
bool busy = true;
#endif

#ifdef HAVE_URING
bool uring_initialized = false;
#endif

ClockCache<std::chrono::steady_clock> steady_clock_cache;

public:
Expand Down Expand Up @@ -185,8 +182,27 @@ public:
steady_clock_cache.flush();
}

void SetVolatile() noexcept;

#ifdef HAVE_URING
[[gnu::pure]]
/**
* Try to enable io_uring support. If this method succeeds,
* GetUring() can be used to obtain a pointer to the queue
* instance.
*
* Throws on error.
*/
void EnableUring(unsigned entries, unsigned flags);
void EnableUring(unsigned entries, struct io_uring_params &params);

void DisableUring() noexcept;

/**
* Returns a pointer to the io_uring queue instance or nullptr
* if io_uring support is not available (or was not enabled
* using EnableUring()).
*/
[[nodiscard]] [[gnu::const]]
Uring::Queue *GetUring() noexcept;
#endif

Expand Down
25 changes: 25 additions & 0 deletions src/event/Thread.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include "util/Domain.hxx"
#include "Log.hxx"

#ifdef HAVE_URING
#include "util/ScopeExit.hxx"
#include <liburing.h>
#endif

static constexpr Domain event_domain("event");

void
Expand Down Expand Up @@ -51,7 +56,27 @@ EventThread::Run() noexcept
"RTIOThread could not get realtime scheduling, continuing anyway: {}",
std::current_exception());
}
} else {
#ifdef HAVE_URING
try {
event_loop.EnableUring(1024, IORING_SETUP_SINGLE_ISSUER);
} catch (...) {
FmtInfo(event_domain,
"Failed to initialize io_uring: {}",
std::current_exception());
}
#endif
}

#ifdef HAVE_URING
AtScopeExit(this) {
/* make sure that the Uring::Manager gets destructed
from within the EventThread, or else its
destruction in another thread will cause assertion
failures */
event_loop.DisableUring();
};
#endif

event_loop.Run();
}
5 changes: 1 addition & 4 deletions src/event/Thread.hxx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project

#ifndef MPD_EVENT_THREAD_HXX
#define MPD_EVENT_THREAD_HXX
#pragma once

#include "Loop.hxx"
#include "thread/Thread.hxx"
Expand Down Expand Up @@ -36,5 +35,3 @@ public:
private:
void Run() noexcept;
};

#endif /* MAIN_NOTIFY_H */

0 comments on commit 00a352f

Please sign in to comment.