Handle FileSystemWatcherInterface::AddPath errors.
On Linux systems, failure to watch a path may be caused by the limit set in /proc/sys/fs/inotify/max_user_watches. This can be demonstrated by creating a directory with a large number of empty subdirectories and adding that test directory as a library. Check that a file is readable before adding a watch. If adding the watch fails, report the error to the user only once. Only add the path to subdir_mapping_ if watch succeeds.
This commit is contained in:
parent
26e12f5006
commit
34a2e86b4b
@ -64,6 +64,7 @@ FilesystemDevice::FilesystemDevice(const QUrl& url, DeviceLister* lister,
|
||||
connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_.get(),
|
||||
SLOT(UpdateCompilations()));
|
||||
connect(watcher_, SIGNAL(ScanStarted(int)), SIGNAL(TaskStarted(int)));
|
||||
connect(watcher_, &LibraryWatcher::Error, app, &Application::AddError);
|
||||
}
|
||||
|
||||
void FilesystemDevice::Init() {
|
||||
|
@ -161,6 +161,7 @@ void Library::Init() {
|
||||
backend_.get(), SLOT(AddOrUpdateSubdirs(SubdirectoryList)));
|
||||
connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_.get(),
|
||||
SLOT(UpdateCompilations()));
|
||||
connect(watcher_, &LibraryWatcher::Error, app_, &Application::AddError);
|
||||
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)),
|
||||
SLOT(CurrentSongChanged(Song)));
|
||||
connect(app_->player(), SIGNAL(Stopped()), SLOT(Stopped()));
|
||||
|
@ -588,11 +588,34 @@ uint LibraryWatcher::GetMtimeForCue(const QString& cue_path) {
|
||||
}
|
||||
|
||||
void LibraryWatcher::AddWatch(const Directory& dir, const QString& path) {
|
||||
if (!QFile::exists(path)) return;
|
||||
QFileInfo info(path);
|
||||
if (!info.exists() || !info.isReadable()) return;
|
||||
|
||||
connect(fs_watcher_, SIGNAL(PathChanged(const QString&)), this,
|
||||
SLOT(DirectoryChanged(const QString&)), Qt::UniqueConnection);
|
||||
fs_watcher_->AddPath(path);
|
||||
if (!fs_watcher_->AddPath(path)) {
|
||||
// Since this may be a system error, don't spam the user.
|
||||
static int errCount = 0;
|
||||
if (errCount++ == 0) {
|
||||
#ifdef Q_OS_LINUX
|
||||
// The Linux implementation of QFileSystemWatcher utilizes inotify, so
|
||||
// the limit in /proc/sys/fs/inotify/max_user_watches may be a problem
|
||||
// in large libraries.
|
||||
const char* fmt =
|
||||
"Failed to watch %1\n"
|
||||
"On a Linux system, this may be due to the inotify max_user_watches "
|
||||
"limit.\n\n"
|
||||
"This error will not be shown again during this session.";
|
||||
#else
|
||||
const char* fmt =
|
||||
"Failed to watch %1 for unknown reasons.\n\n"
|
||||
"This error will not be shown again during this session.";
|
||||
#endif
|
||||
emit Error(tr(fmt).arg(path));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
subdir_mapping_[path] = dir;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,8 @@ signals:
|
||||
|
||||
void ScanStarted(int task_id);
|
||||
|
||||
void Error(const QString& message);
|
||||
|
||||
public slots:
|
||||
void ReloadSettings();
|
||||
void AddDirectory(const Directory& dir, const SubdirectoryList& subdirs);
|
||||
|
Loading…
x
Reference in New Issue
Block a user