wayland: Bump RLIMIT_NOFILE limit
As a wayland compositor kwin can hold many open file descriptors and therefore it's easier for it to hit the soft file descriptor limit. This change makes kwin_wayland bump the soft file descriptor limit to the hard limit. With systemd, it's usually 500K. In order to prevent causing mess in child processes, pthread_atfork() is used to register a handler which will be invoked in the child process after fork() in order to restore RLIMIT_NOFILE to its original value.
This commit is contained in:
parent
2178f26e7b
commit
ed90be0783
1 changed files with 38 additions and 0 deletions
|
@ -43,6 +43,7 @@
|
|||
#endif
|
||||
|
||||
#include <sched.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
@ -58,6 +59,36 @@ Q_IMPORT_PLUGIN(ScreencastManagerFactory)
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
static rlimit originalNofileLimit = {
|
||||
.rlim_cur = 0,
|
||||
.rlim_max = 0,
|
||||
};
|
||||
|
||||
static bool bumpNofileLimit()
|
||||
{
|
||||
if (getrlimit(RLIMIT_NOFILE, &originalNofileLimit) == -1) {
|
||||
std::cerr << "Failed to bump RLIMIT_NOFILE limit, getrlimit() failed: " << strerror(errno) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
rlimit limit = originalNofileLimit;
|
||||
limit.rlim_cur = limit.rlim_max;
|
||||
|
||||
if (setrlimit(RLIMIT_NOFILE, &limit) == -1) {
|
||||
std::cerr << "Failed to bump RLIMIT_NOFILE limit, setrlimit() failed: " << strerror(errno) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void restoreNofileLimit()
|
||||
{
|
||||
if (setrlimit(RLIMIT_NOFILE, &originalNofileLimit) == -1) {
|
||||
std::cerr << "Failed to restore RLIMIT_NOFILE limit, legacy apps might be broken" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void sighandler(int)
|
||||
{
|
||||
QApplication::exit();
|
||||
|
@ -322,6 +353,13 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
// It's easy to exceed the file descriptor limit because many things are backed using fds
|
||||
// nowadays, e.g. dmabufs, shm buffers, etc. Bump the RLIMIT_NOFILE limit to handle that.
|
||||
// Some apps may still use select(), so we reset the limit to its original value in fork().
|
||||
if (KWin::bumpNofileLimit()) {
|
||||
pthread_atfork(nullptr, nullptr, KWin::restoreNofileLimit);
|
||||
}
|
||||
|
||||
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
|
||||
|
||||
// enforce our internal qpa plugin, unfortunately command line switch has precedence
|
||||
|
|
Loading…
Reference in a new issue