/*
* Copyright (C) 2018 Nicolas Bonnefon and other contributors
*
* This file is part of glogg.
*
* glogg is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* glogg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with glogg. If not, see .
*/
#ifndef KQUEUEWATCHTOWERDRIVER_H
#define KQUEUEWATCHTOWERDRIVER_H
#include
#include
#include
template
struct ObservedFile;
template
class ObservedFileList;
class KQueueWatchTowerDriver {
public:
class FileId {
public:
friend class KQueueWatchTowerDriver;
FileId() { fd_ = -1; }
bool operator==( const FileId& other ) const
{ return fd_ == other.fd_; }
private:
FileId( int fd ) { fd_ = fd; }
int fd_;
};
class DirId {
public:
friend class KQueueWatchTowerDriver;
DirId() { wd_ = -1; }
bool operator==( const DirId& other ) const
{ return wd_ == other.wd_; }
bool valid() const
{ return (wd_ != -1); }
private:
DirId( int wd ) { wd_ = wd; }
int wd_;
};
class SymlinkId {
public:
friend class KQueueWatchTowerDriver;
SymlinkId() { wd_ = -1; }
bool operator==( const SymlinkId& other ) const
{ return wd_ == other.wd_; }
private:
SymlinkId( int wd ) { wd_ = wd; }
int wd_;
};
// Dummy class for inotify
class FileChangeToken {
public:
FileChangeToken() {}
FileChangeToken( const std::string& ) {}
void readFromFile( const std::string& ) {}
bool operator!=( const FileChangeToken& )
{ return true; }
};
#ifdef HAS_TEMPLATE_ALIASES
using KQueueObservedFile = ObservedFile;
using KQueueObservedFileList = ObservedFileList;
#else
typedef ObservedFile KQueueObservedFile;
typedef ObservedFileList KQueueObservedFileList;
#endif
// Default constructor
KQueueWatchTowerDriver();
~KQueueWatchTowerDriver();
// No copy/assign/move please
KQueueWatchTowerDriver( const KQueueWatchTowerDriver& ) = delete;
KQueueWatchTowerDriver& operator=( const KQueueWatchTowerDriver& ) = delete;
KQueueWatchTowerDriver( const KQueueWatchTowerDriver&& ) = delete;
KQueueWatchTowerDriver& operator=( const KQueueWatchTowerDriver&& ) = delete;
FileId addFile( const std::string& file_name );
SymlinkId addSymlink( const std::string& file_name );
DirId addDir( const std::string& file_name );
void removeFile( const FileId& file_id );
void removeSymlink( const SymlinkId& symlink_id );
void removeDir( const DirId& dir_id );
// Wait for an event for the OS, treat it and
// return a list of files to notify about.
// This must be called with the lock on the list held,
// the function will unlock it temporary whilst blocking.
// Also returns a list of file that need readding
// (because of renames/symlink...)
std::vector waitAndProcessEvents(
KQueueObservedFileList* list,
std::unique_lock* list_mutex,
std::vector* files_needing_readding,
int timeout_ms );
// Interrupt waitAndProcessEvents if it is blocking.
void interruptWait();
private:
// Only written at initialisation so no protection needed.
const int kqueue_fd_;
// Breaking pipe
int breaking_pipe_read_fd_;
int breaking_pipe_write_fd_;
/*
// Private member functions
size_t processINotifyEvent( const struct inotify_event* event,
KQueueObservedFileList* list,
std::vector* files_to_notify,
std::vector* files_needing_readding );
*/
};
#endif