Merge pull request #6533 from jbroadus/inotify-errors

Inotify errors
This commit is contained in:
John Maguire 2020-01-18 13:04:55 +00:00 committed by GitHub
commit 969c158cee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 38 additions and 8 deletions

View File

@ -27,7 +27,7 @@ class FileSystemWatcherInterface : public QObject {
public: public:
explicit FileSystemWatcherInterface(QObject* parent = nullptr); explicit FileSystemWatcherInterface(QObject* parent = nullptr);
virtual void Init() {} virtual void Init() {}
virtual void AddPath(const QString& path) = 0; virtual bool AddPath(const QString& path) = 0;
virtual void RemovePath(const QString& path) = 0; virtual void RemovePath(const QString& path) = 0;
virtual void Clear() = 0; virtual void Clear() = 0;

View File

@ -35,7 +35,7 @@ class MacFSListener : public FileSystemWatcherInterface {
public: public:
explicit MacFSListener(QObject* parent = nullptr); explicit MacFSListener(QObject* parent = nullptr);
void Init(); void Init();
void AddPath(const QString& path); bool AddPath(const QString& path);
void RemovePath(const QString& path); void RemovePath(const QString& path);
void Clear(); void Clear();

View File

@ -52,10 +52,11 @@ void MacFSListener::EventStreamCallback(
} }
} }
void MacFSListener::AddPath(const QString& path) { bool MacFSListener::AddPath(const QString& path) {
Q_ASSERT(run_loop_); Q_ASSERT(run_loop_);
paths_.insert(path); paths_.insert(path);
UpdateStreamAsync(); UpdateStreamAsync();
return true;
} }
void MacFSListener::RemovePath(const QString& path) { void MacFSListener::RemovePath(const QString& path) {

View File

@ -27,7 +27,9 @@ QtFSListener::QtFSListener(QObject* parent)
SIGNAL(PathChanged(const QString&))); SIGNAL(PathChanged(const QString&)));
} }
void QtFSListener::AddPath(const QString& path) { watcher_.addPath(path); } bool QtFSListener::AddPath(const QString& path) {
return watcher_.addPath(path);
}
void QtFSListener::RemovePath(const QString& path) { void QtFSListener::RemovePath(const QString& path) {
watcher_.removePath(path); watcher_.removePath(path);

View File

@ -28,7 +28,7 @@ class QtFSListener : public FileSystemWatcherInterface {
Q_OBJECT Q_OBJECT
public: public:
explicit QtFSListener(QObject* parent); explicit QtFSListener(QObject* parent);
virtual void AddPath(const QString& path); virtual bool AddPath(const QString& path);
virtual void RemovePath(const QString& path); virtual void RemovePath(const QString& path);
virtual void Clear(); virtual void Clear();

View File

@ -64,6 +64,7 @@ FilesystemDevice::FilesystemDevice(const QUrl& url, DeviceLister* lister,
connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_.get(), connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_.get(),
SLOT(UpdateCompilations())); SLOT(UpdateCompilations()));
connect(watcher_, SIGNAL(ScanStarted(int)), SIGNAL(TaskStarted(int))); connect(watcher_, SIGNAL(ScanStarted(int)), SIGNAL(TaskStarted(int)));
connect(watcher_, &LibraryWatcher::Error, app, &Application::AddError);
} }
void FilesystemDevice::Init() { void FilesystemDevice::Init() {

View File

@ -161,6 +161,7 @@ void Library::Init() {
backend_.get(), SLOT(AddOrUpdateSubdirs(SubdirectoryList))); backend_.get(), SLOT(AddOrUpdateSubdirs(SubdirectoryList)));
connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_.get(), connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_.get(),
SLOT(UpdateCompilations())); SLOT(UpdateCompilations()));
connect(watcher_, &LibraryWatcher::Error, app_, &Application::AddError);
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)),
SLOT(CurrentSongChanged(Song))); SLOT(CurrentSongChanged(Song)));
connect(app_->player(), SIGNAL(Stopped()), SLOT(Stopped())); connect(app_->player(), SIGNAL(Stopped()), SLOT(Stopped()));

View File

@ -588,11 +588,34 @@ uint LibraryWatcher::GetMtimeForCue(const QString& cue_path) {
} }
void LibraryWatcher::AddWatch(const Directory& dir, const QString& 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, connect(fs_watcher_, SIGNAL(PathChanged(const QString&)), this,
SLOT(DirectoryChanged(const QString&)), Qt::UniqueConnection); 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; subdir_mapping_[path] = dir;
} }

View File

@ -68,6 +68,8 @@ signals:
void ScanStarted(int task_id); void ScanStarted(int task_id);
void Error(const QString& message);
public slots: public slots:
void ReloadSettings(); void ReloadSettings();
void AddDirectory(const Directory& dir, const SubdirectoryList& subdirs); void AddDirectory(const Directory& dir, const SubdirectoryList& subdirs);

View File

@ -55,7 +55,7 @@ void ErrorDialog::UpdateContent() {
QString html; QString html;
for (const QString& message : current_messages_) { for (const QString& message : current_messages_) {
if (!html.isEmpty()) html += "<hr/>"; if (!html.isEmpty()) html += "<hr/>";
html += message.toHtmlEscaped(); html += message.toHtmlEscaped().replace("\n", "<br>");
} }
ui_->messages->setHtml(html); ui_->messages->setHtml(html);
} }