Skip to content
Snippets Groups Projects
Commit 297a8b7d authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: move fileMonitor stat vs. inotify to internal class

- avoids potential mismatches between header and courtesy binaries
parent 435013ea
Branches
Tags
No related merge requests found
...@@ -17,7 +17,7 @@ wmakeLnInclude OpenFOAM ...@@ -17,7 +17,7 @@ wmakeLnInclude OpenFOAM
wmakeLnInclude OSspecific/$WM_OSTYPE wmakeLnInclude OSspecific/$WM_OSTYPE
Pstream/Allwmake Pstream/Allwmake
wmake libo OSspecific/$WM_OSTYPE OSspecific/$WM_OSTYPE/Allwmake
wmake libso OpenFOAM wmake libso OpenFOAM
wmake libso lagrangian/basic wmake libso lagrangian/basic
......
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
#
# use <sys/inotify.h> if available (Linux)
# unless otherwise specified (with FOAM_USE_STAT)
#
# eg, ./Allwmake FOAM_USE_STAT
#
if [ -f /usr/include/sys/inotify.h -a "${1%USE_STAT}" = "$1" ]
then
unset FOAM_FILE_MONITOR
else
export FOAM_FILE_MONITOR="-DFOAM_USE_STAT"
fi
# make (non-shared) object
wmake libo
# ----------------------------------------------------------------- end-of-file
#ifdef SunOS64 EXE_INC = $(FOAM_FILE_MONITOR)
EXE_INC = -DFOAM_USE_STAT
#endif
...@@ -37,7 +37,6 @@ Class ...@@ -37,7 +37,6 @@ Class
# include "regIOobject.H" // for fileModificationSkew symbol # include "regIOobject.H" // for fileModificationSkew symbol
#else #else
# include <sys/inotify.h> # include <sys/inotify.h>
# include <stropts.h>
# include <sys/ioctl.h> # include <sys/ioctl.h>
#endif #endif
...@@ -49,8 +48,8 @@ template<> ...@@ -49,8 +48,8 @@ template<>
const char* Foam::NamedEnum<Foam::fileMonitor::fileState, 3>::names[] = const char* Foam::NamedEnum<Foam::fileMonitor::fileState, 3>::names[] =
{ {
"unmodified", "unmodified",
"deleted", "modified",
"modified" "deleted"
}; };
const Foam::NamedEnum<Foam::fileMonitor::fileState, 3> const Foam::NamedEnum<Foam::fileMonitor::fileState, 3>
Foam::fileMonitor::fileStateNames_; Foam::fileMonitor::fileStateNames_;
...@@ -58,7 +57,7 @@ const Foam::NamedEnum<Foam::fileMonitor::fileState, 3> ...@@ -58,7 +57,7 @@ const Foam::NamedEnum<Foam::fileMonitor::fileState, 3>
namespace Foam namespace Foam
{ {
// Reduction operator for PackedList of fileState //- Reduction operator for PackedList of fileState
class reduceFileStates class reduceFileStates
{ {
public: public:
...@@ -89,7 +88,7 @@ namespace Foam ...@@ -89,7 +88,7 @@ namespace Foam
} }
}; };
// Combine operator for PackedList of fileState //- Combine operator for PackedList of fileState
class combineReduceFileStates class combineReduceFileStates
{ {
public: public:
...@@ -98,22 +97,101 @@ namespace Foam ...@@ -98,22 +97,101 @@ namespace Foam
x = reduceFileStates()(x, y); x = reduceFileStates()(x, y);
} }
}; };
//! @cond internalClass
//- Internal tracking via stat(3p) or inotify(7)
class fileMonitorWatcher
{
public:
#ifdef FOAM_USE_STAT
//- From watch descriptor to modified time
HashTable<label, time_t> lastMod;
//- initialize HashTable size
inline fileMonitorWatcher(const label sz = 20)
:
lastMod(sz)
{}
inline label addWatch(const fileName& fName)
{
const label watchFd = lastMod.size();
lastMod.insert(watchFd, lastModified(fName));
return watchFd;
}
inline bool removeWatch(const label watchFd)
{
return lastMod.erase(watchFd);
}
#else
//- File descriptor for the inotify instance
int fd;
//- Pre-allocated structure containing file descriptors
fd_set fdSet;
//- initialize inotify
inline fileMonitorWatcher(const label dummy = 0)
:
fd(inotify_init())
{
// Add notify descriptor to select fd_set
FD_ZERO(&fdSet);
FD_SET(fd, &fdSet);
}
//- test if file descriptor is set
inline bool isSet() const
{
return FD_ISSET(fd, &fdSet);
}
//- reset file descriptor
inline void reset()
{
FD_SET(fd, &fdSet);
}
inline label addWatch(const fileName& fName)
{
return inotify_add_watch
(
fd,
fName.c_str(),
// IN_ALL_EVENTS
IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MODIFY
);
}
inline bool removeWatch(const label watchFd)
{
return inotify_rm_watch(fd, int(watchFd)) == 0;
}
#endif
};
//! @endcond
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
#ifdef FOAM_USE_STAT
void Foam::fileMonitor::checkFiles() const void Foam::fileMonitor::checkFiles() const
{ {
#ifdef FOAM_USE_STAT
for for
( (
HashTable<label, time_t>::iterator iter = lastModified_.begin(); HashTable<label, time_t>::iterator iter = watcher_->lastMod.begin();
iter != lastModified_.end(); iter != watcher_->lastMod.end();
++iter ++iter
) )
{ {
label watchFd = iter.key(); const label watchFd = iter.key();
const fileName& fName = watchFile_[watchFd]; const fileName& fName = watchFile_[watchFd];
time_t newTime = lastModified(fName); time_t newTime = lastModified(fName);
...@@ -135,21 +213,18 @@ void Foam::fileMonitor::checkFiles() const ...@@ -135,21 +213,18 @@ void Foam::fileMonitor::checkFiles() const
} }
} }
} }
}
#else #else
void Foam::fileMonitor::checkFiles() const
{
while (true) while (true)
{ {
struct timeval zeroTimeout = {0, 0}; struct timeval zeroTimeout = {0, 0};
int ready = select int ready = select
( (
inotifyFd_+1, // num filedescriptors in watchSet_ watcher_->fd+1, // num filedescriptors in fdSet
&watchSet_, // watchSet_ with only inotifyFd &(watcher_->fdSet), // fdSet with only inotifyFd
NULL, NULL, // No writefds
NULL, NULL, // No errorfds
&zeroTimeout &zeroTimeout // eNo timeout
); );
if (ready < 0) if (ready < 0)
...@@ -158,14 +233,14 @@ void Foam::fileMonitor::checkFiles() const ...@@ -158,14 +233,14 @@ void Foam::fileMonitor::checkFiles() const
<< "Problem in issuing select." << "Problem in issuing select."
<< abort(FatalError); << abort(FatalError);
} }
else if (FD_ISSET(inotifyFd_, &watchSet_)) else if (watcher_->isSet())
{ {
struct inotify_event inotifyEvent; struct inotify_event inotifyEvent;
// Read first event // Read first event
ssize_t nBytes = read ssize_t nBytes = read
( (
inotifyFd_, watcher_->fd,
&inotifyEvent, &inotifyEvent,
sizeof(inotifyEvent) sizeof(inotifyEvent)
); );
...@@ -178,9 +253,9 @@ void Foam::fileMonitor::checkFiles() const ...@@ -178,9 +253,9 @@ void Foam::fileMonitor::checkFiles() const
<< abort(FatalError); << abort(FatalError);
} }
//Pout<< "mask:" << inotifyEvent.mask << endl; // Pout<< "mask:" << inotifyEvent.mask << nl
//Pout<< "watchFd:" << inotifyEvent.wd << endl; // << "watchFd:" << inotifyEvent.wd << nl
//Pout<< "watchName:" << watchFile_[inotifyEvent.wd] << endl; // << "watchName:" << watchFile_[inotifyEvent.wd] << endl;
switch (inotifyEvent.mask) switch (inotifyEvent.mask)
{ {
...@@ -204,51 +279,37 @@ void Foam::fileMonitor::checkFiles() const ...@@ -204,51 +279,37 @@ void Foam::fileMonitor::checkFiles() const
} }
else else
{ {
// No data. Reset watchSet_ // No data - reset
FD_SET(inotifyFd_, &watchSet_); watcher_->reset();
return; return;
} }
} }
}
#endif #endif
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Null constructor
#ifdef FOAM_USE_STAT
Foam::fileMonitor::fileMonitor() Foam::fileMonitor::fileMonitor()
: :
state_(20), state_(20),
watchFile_(20), watchFile_(20),
lastModified_(20) watcher_(new fileMonitorWatcher(20))
{} {}
#else
Foam::fileMonitor::fileMonitor()
:
state_(20),
watchFile_(20),
inotifyFd_(inotify_init())
{
//- Add notify descriptor to select set
FD_ZERO(&watchSet_);
FD_SET(inotifyFd_, &watchSet_);
}
#endif
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fileMonitor::~fileMonitor() Foam::fileMonitor::~fileMonitor()
{ {
// Remove any remaining files // Remove watch on any remaining files
List<label> watchFds(state_.toc()); List<label> watchFds(state_.toc());
forAll(watchFds, i) forAll(watchFds, i)
{ {
removeWatch(watchFds[i]); removeWatch(watchFds[i]);
} }
delete watcher_;
} }
...@@ -257,18 +318,7 @@ Foam::fileMonitor::~fileMonitor() ...@@ -257,18 +318,7 @@ Foam::fileMonitor::~fileMonitor()
Foam::label Foam::fileMonitor::addWatch(const fileName& fName) Foam::label Foam::fileMonitor::addWatch(const fileName& fName)
{ {
#ifdef FOAM_USE_STAT const label watchFd = watcher_->addWatch(fName);
label watchFd = lastModified_.size();
lastModified_.insert(watchFd, lastModified(fName));
#else
label watchFd = inotify_add_watch
(
inotifyFd_,
fName.c_str(),
//IN_ALL_EVENTS
IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MODIFY
);
#endif
if (debug) if (debug)
{ {
...@@ -300,11 +350,7 @@ bool Foam::fileMonitor::removeWatch(const label watchFd) ...@@ -300,11 +350,7 @@ bool Foam::fileMonitor::removeWatch(const label watchFd)
state_.erase(watchFd); state_.erase(watchFd);
watchFile_.erase(watchFd); watchFile_.erase(watchFd);
#ifdef FOAM_USE_STAT return watcher_->removeWatch(watchFd);
return lastModified_.erase(watchFd);
#else
return inotify_rm_watch(inotifyFd_, int(watchFd)) == 0;
#endif
} }
...@@ -331,7 +377,7 @@ void Foam::fileMonitor::updateStates(const bool syncPar) const ...@@ -331,7 +377,7 @@ void Foam::fileMonitor::updateStates(const bool syncPar) const
label i = 0; label i = 0;
forAllConstIter(Map<fileState>, state_, iter) forAllConstIter(Map<fileState>, state_, iter)
{ {
stats[i++] = (unsigned int)(iter()); stats[i++] = static_cast<unsigned int>(iter());
} }
// Save local state for warning message below // Save local state for warning message below
PackedList<2> thisProcStats(stats); PackedList<2> thisProcStats(stats);
...@@ -378,7 +424,7 @@ void Foam::fileMonitor::updateStates(const bool syncPar) const ...@@ -378,7 +424,7 @@ void Foam::fileMonitor::updateStates(const bool syncPar) const
void Foam::fileMonitor::setUnmodified(const label watchFd) void Foam::fileMonitor::setUnmodified(const label watchFd)
{ {
#ifdef FOAM_USE_STAT #ifdef FOAM_USE_STAT
lastModified_[watchFd] = lastModified(watchFile_[watchFd]); watcher_->lastMod[watchFd] = lastModified(watchFile_[watchFd]);
#endif #endif
Map<fileState>::iterator iter = state_.find(watchFd); Map<fileState>::iterator iter = state_.find(watchFd);
......
...@@ -27,13 +27,13 @@ Class ...@@ -27,13 +27,13 @@ Class
Description Description
Checking for changes to files. Checking for changes to files.
!!!!!!!NOTE: Note
Default is to use inotify (Linux specific, since 2.6.13) The default is to use inotify (Linux specific, since 2.6.13)
Compile with FOAM_USE_STAT to use the stat function call. Compiling with FOAM_USE_STAT (or if /usr/include/sys/inotify.h
does not exist) uses the stat function call.
- works fine except when a file is deleted and recreated:
- works fine except for if file gets deleted and recreated
it stops monitoring the file! it stops monitoring the file!
(does work though if the file gets moved) (does work though if the file gets moved)
...@@ -48,7 +48,6 @@ SourceFiles ...@@ -48,7 +48,6 @@ SourceFiles
#include <sys/types.h> #include <sys/types.h>
#include "Map.H" #include "Map.H"
#include "NamedEnum.H" #include "NamedEnum.H"
#include "labelList.H"
#include "className.H" #include "className.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
...@@ -57,9 +56,10 @@ namespace Foam ...@@ -57,9 +56,10 @@ namespace Foam
{ {
class fileMonitor; class fileMonitor;
class fileMonitorWatcher;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class fileMonitor Declaration Class fileMonitor Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class fileMonitor class fileMonitor
...@@ -73,8 +73,8 @@ public: ...@@ -73,8 +73,8 @@ public:
enum fileState enum fileState
{ {
UNMODIFIED = 0, UNMODIFIED = 0,
DELETED = 1, MODIFIED = 1,
MODIFIED = 2 DELETED = 2,
}; };
static const NamedEnum<fileState, 3> fileStateNames_; static const NamedEnum<fileState, 3> fileStateNames_;
...@@ -84,22 +84,16 @@ private: ...@@ -84,22 +84,16 @@ private:
//- State for all watchFds //- State for all watchFds
mutable Map<fileState> state_; mutable Map<fileState> state_;
//- From watch descriptor to filename //- From watch descriptor to filename
HashTable<fileName, label> watchFile_; HashTable<fileName, label> watchFile_;
#ifdef FOAM_USE_STAT //- Watch mechanism (stat or inotify)
mutable fileMonitorWatcher *watcher_;
//- From watch descriptor to modified time
mutable HashTable<label, time_t> lastModified_;
#else
//- File descriptor for the inotify instance
int inotifyFd_;
//- Pre-allocated structure containing file descriptors // Private Member Functions
mutable fd_set watchSet_;
#endif
//- Update state_ from any events. //- Update state_ from any events.
void checkFiles() const; void checkFiles() const;
...@@ -121,14 +115,13 @@ public: ...@@ -121,14 +115,13 @@ public:
fileMonitor(); fileMonitor();
// Destructor //- Destructor
~fileMonitor();
~fileMonitor();
// Member Functions // Member Functions
//- Add file to watch. Returns watch descriptor //- Add file to watch. Return watch descriptor
label addWatch(const fileName&); label addWatch(const fileName&);
//- Remove file to watch. Return true if successful //- Remove file to watch. Return true if successful
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment