db/update/InotifySource: migrate from class Error to C++ exceptions

This commit is contained in:
Max Kellermann 2016-10-28 10:23:05 +02:00
parent 1560749579
commit 4bd67bc298
4 changed files with 57 additions and 78 deletions

View File

@ -20,9 +20,9 @@
#include "config.h"
#include "InotifySource.hxx"
#include "InotifyDomain.hxx"
#include "util/Error.hxx"
#include "system/FileDescriptor.hxx"
#include "system/FatalError.hxx"
#include "system/Error.hxx"
#include "Log.hxx"
#include <sys/inotify.h>
@ -67,37 +67,30 @@ InotifySource::OnSocketReady(gcc_unused unsigned flags)
return true;
}
inline
static int
InotifyInit()
{
FileDescriptor fd;
if (!fd.CreateInotify())
throw MakeErrno("inotify_init() has failed");
return fd.Get();
}
InotifySource::InotifySource(EventLoop &_loop,
mpd_inotify_callback_t _callback, void *_ctx,
FileDescriptor _fd)
:SocketMonitor(_fd.Get(), _loop),
mpd_inotify_callback_t _callback, void *_ctx)
:SocketMonitor(InotifyInit(), _loop),
callback(_callback), callback_ctx(_ctx)
{
ScheduleRead();
}
InotifySource *
InotifySource::Create(EventLoop &loop,
mpd_inotify_callback_t callback, void *callback_ctx,
Error &error)
{
FileDescriptor fd;
if (!fd.CreateInotify()) {
error.SetErrno("inotify_init() has failed");
return nullptr;
}
return new InotifySource(loop, callback, callback_ctx, fd);
}
int
InotifySource::Add(const char *path_fs, unsigned mask, Error &error)
InotifySource::Add(const char *path_fs, unsigned mask)
{
int wd = inotify_add_watch(Get(), path_fs, mask);
if (wd < 0)
error.SetErrno("inotify_add_watch() has failed");
throw MakeErrno("inotify_add_watch() has failed");
return wd;
}

View File

@ -23,7 +23,6 @@
#include "event/SocketMonitor.hxx"
#include "Compiler.h"
class Error;
class FileDescriptor;
typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask,
@ -33,33 +32,31 @@ class InotifySource final : private SocketMonitor {
mpd_inotify_callback_t callback;
void *callback_ctx;
InotifySource(EventLoop &_loop,
mpd_inotify_callback_t callback, void *ctx,
FileDescriptor fd);
public:
/**
* Creates a new inotify source and registers it in the
* #EventLoop.
*
* Throws #std::system_error on error.
*
* @param callback a callback invoked for events received from
* the kernel
*/
InotifySource(EventLoop &_loop,
mpd_inotify_callback_t callback, void *ctx);
~InotifySource() {
Close();
}
/**
* Creates a new inotify source and registers it in the
* #EventLoop.
*
* @param callback a callback invoked for events received from
* the kernel
*/
static InotifySource *Create(EventLoop &_loop,
mpd_inotify_callback_t callback,
void *ctx,
Error &error);
/**
* Adds a path to the notify list.
*
* @return a watch descriptor or -1 on error
* Throws #std::system_error on error.
*
* @return a watch descriptor
*/
int Add(const char *path_fs, unsigned mask, Error &error);
int Add(const char *path_fs, unsigned mask);
/**
* Removes a path from the notify list.

View File

@ -25,7 +25,6 @@
#include "storage/StorageInterface.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/FileInfo.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include <string>
@ -157,7 +156,6 @@ static void
recursive_watch_subdirectories(WatchDirectory *directory,
const AllocatedPath &path_fs, unsigned depth)
{
Error error;
DIR *dir;
struct dirent *ent;
@ -187,22 +185,23 @@ recursive_watch_subdirectories(WatchDirectory *directory,
AllocatedPath::Build(path_fs, ent->d_name);
FileInfo fi;
if (!GetFileInfo(child_path_fs, fi, error)) {
LogError(error);
error.Clear();
try {
fi = FileInfo(child_path_fs);
} catch (const std::runtime_error &e) {
LogError(e);
continue;
}
if (!fi.IsDirectory())
continue;
ret = inotify_source->Add(child_path_fs.c_str(), IN_MASK,
error);
if (ret < 0) {
FormatError(error,
try {
ret = inotify_source->Add(child_path_fs.c_str(),
IN_MASK);
} catch (const std::runtime_error &e) {
FormatError(e,
"Failed to register %s",
child_path_fs.c_str());
error.Clear();
continue;
}
@ -299,20 +298,22 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
return;
}
Error error;
inotify_source = InotifySource::Create(loop,
mpd_inotify_callback, nullptr,
error);
if (inotify_source == nullptr) {
LogError(error);
try {
inotify_source = new InotifySource(loop,
mpd_inotify_callback,
nullptr);
} catch (const std::runtime_error &e) {
LogError(e);
return;
}
inotify_max_depth = max_depth;
int descriptor = inotify_source->Add(path.c_str(), IN_MASK, error);
if (descriptor < 0) {
LogError(error);
int descriptor;
try {
descriptor = inotify_source->Add(path.c_str(), IN_MASK);
} catch (const std::runtime_error &e) {
LogError(e);
delete inotify_source;
inotify_source = nullptr;
return;

View File

@ -21,7 +21,6 @@
#include "ShutdownHandler.hxx"
#include "db/update/InotifySource.hxx"
#include "event/Loop.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include <sys/inotify.h>
@ -41,7 +40,7 @@ my_inotify_callback(gcc_unused int wd, unsigned mask,
}
int main(int argc, char **argv)
{
try {
const char *path;
if (argc != 2) {
@ -54,24 +53,13 @@ int main(int argc, char **argv)
EventLoop event_loop;
const ShutdownHandler shutdown_handler(event_loop);
Error error;
InotifySource *source = InotifySource::Create(event_loop,
my_inotify_callback,
nullptr, error);
if (source == NULL) {
LogError(error);
return EXIT_FAILURE;
}
int descriptor = source->Add(path, IN_MASK, error);
if (descriptor < 0) {
delete source;
LogError(error);
return EXIT_FAILURE;
}
InotifySource source(event_loop, my_inotify_callback, nullptr);
source.Add(path, IN_MASK);
event_loop.Run();
delete source;
return EXIT_SUCCESS;
} catch (const std::runtime_error &e) {
LogError(e);
return EXIT_FAILURE;
}