Add a warning for low RLIMIT_RTTIME values

This will make it much easier to spot issues caused by PipeWire.
This commit is contained in:
Robbert van der Helm
2021-05-27 14:22:58 +02:00
parent 0d3850e837
commit 68d5d33cba
2 changed files with 41 additions and 4 deletions
+3
View File
@@ -24,6 +24,9 @@ Versioning](https://semver.org/spec/v2.0.0.html).
allows **ujam** plugins and other plugins made with the Gorilla Engine such as
the **LoopCloud** plugins to function correctly as those plugins will throw a
seemingly unrelated error when they output to a pipe.
- Added a small warning on initialization when `RLIMIT_RTTIME` is set to some
small value. This happens when using PipeWire, and it can cause crashes when
using loading plugins.
### Changed
+38 -4
View File
@@ -22,11 +22,21 @@
// Generated inside of the build directory
#include <src/common/config/config.h>
#include <src/common/config/version.h>
#include <sys/resource.h>
#include "../../common/configuration.h"
#include "../../common/utils.h"
#include "../host-process.h"
/**
* PipeWire uses rtkit, and both set `RLIMIT_RTTIME` to some low value. Normally
* this is kept at unlimited, and low values can cause the host process to get
* terminated during initialization because some plugins may take longer than
* the default 200ms to load. We'll show a warning when the realtime CPU time
* limit is not unlimited (`-1`/`RLIM_INFINITY`) and below this value.
*/
constexpr int rttime_min_safe_threshold = 30'000'000;
/**
* Handles all common operations for hosting plugins such as initializing up the
* plugin host process, setting up the logger, and logging debug information on
@@ -122,9 +132,31 @@ class PluginBridge {
<< "'" << std::endl;
init_msg << "plugin type: '"
<< plugin_type_to_string(info.plugin_type) << "'" << std::endl;
init_msg << "realtime: '"
<< (has_realtime_priority.get() ? "yes" : "no") << "'"
<< std::endl;
init_msg << "realtime: ";
if (has_realtime_priority.get()) {
// Warn if `RLIMIT_RTTIME` is set to some low value. This can happen
// when using PipeWire.
if (auto rttime_limit = get_rttime_limit()) {
if (*rttime_limit != RLIM_INFINITY &&
*rttime_limit < rttime_min_safe_threshold) {
init_msg << "'yes-ish, see below'" << std::endl;
init_msg << std::endl;
init_msg << " RLIMIT_RTTIME is set to " << *rttime_limit
<< " us. This can happen when" << std::endl;
init_msg << " using PipeWire. yabridge may crash when "
<< "loading plugins" << std::endl;
init_msg << " until you fix this." << std::endl;
init_msg << std::endl;
} else {
init_msg << "'yes'" << std::endl;
}
} else {
init_msg << "'WARNING: Could not fetch RLIMIT_RTTIME'"
<< std::endl;
}
} else {
init_msg << "'no'" << std::endl;
}
init_msg << "sockets: '" << sockets.base_dir.string() << "'"
<< std::endl;
@@ -339,7 +371,9 @@ class PluginBridge {
/**
* Whether this process runs with realtime priority. This is set on the
* thread that's relaying STDOUT and STDERR output from Wine, hence the need
* for a future.
* for a future. We won't change the scheduler properties on the thread
* that's initializing the plugin because some DAWs may do that from the UI
* thread.
*/
std::future<bool> has_realtime_priority;