Skip to content

Commit

Permalink
Dep: Add efsw (entropia file system watcher)
Browse files Browse the repository at this point in the history
* Uses system API's which reduces the overhead
  instead of checking periodically for changes.
* Will be used in the hotswap system to reload
  shared libraries on changes.
  • Loading branch information
Naios committed Mar 24, 2016
1 parent d024314 commit 46daaf7
Show file tree
Hide file tree
Showing 79 changed files with 10,579 additions and 1 deletion.
1 change: 1 addition & 0 deletions dep/CMakeLists.txt
Expand Up @@ -35,6 +35,7 @@ if(SERVERS)
add_subdirectory(readline)
add_subdirectory(gsoap)
add_subdirectory(rapidjson)
add_subdirectory(efsw)
endif()

if(TOOLS)
Expand Down
4 changes: 4 additions & 0 deletions dep/PackageList.txt
Expand Up @@ -16,6 +16,10 @@ cppformat (type safe format library)
https://github.com/cppformat/cppformat
Version: 5174b8ca281426af604b85fdf53be8a748b33f56

efws (Entropia File System Watcher - crossplatform file system watcher)
https://bitbucket.org/SpartanJ/efsw
ff0b69daeca1edf7785a8a580518e462be5a6f3d

G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
http://g3d.sourceforge.net/
Version: 9.0-Release r4036
Expand Down
5 changes: 5 additions & 0 deletions dep/efsw/.hg_archival.txt
@@ -0,0 +1,5 @@
repo: 78c2ea8c48b213ee0078d6326a1dd719d0844764
node: ff0b69daeca1edf7785a8a580518e462be5a6f3d
branch: default
latesttag: null
latesttagdistance: 144
85 changes: 85 additions & 0 deletions dep/efsw/CMakeLists.txt
@@ -0,0 +1,85 @@
if (WITH_DYNAMIC_LINKING)
set(SRCS
src/efsw/DirectorySnapshot.cpp
src/efsw/DirectorySnapshotDiff.cpp
src/efsw/DirWatcherGeneric.cpp
src/efsw/FileInfo.cpp
src/efsw/FileSystem.cpp
src/efsw/FileWatcher.cpp
src/efsw/FileWatcherCWrapper.cpp
src/efsw/FileWatcherGeneric.cpp
src/efsw/FileWatcherImpl.cpp
src/efsw/Log.cpp
src/efsw/Mutex.cpp
src/efsw/String.cpp
src/efsw/System.cpp
src/efsw/Thread.cpp
src/efsw/Watcher.cpp
src/efsw/WatcherGeneric.cpp)

if(WIN32)
list(APPEND SRCS
src/efsw/platform/win/FileSystemImpl.cpp
src/efsw/platform/win/MutexImpl.cpp
src/efsw/platform/win/SystemImpl.cpp
src/efsw/platform/win/ThreadImpl.cpp)
else()
list(APPEND SRCS
src/efsw/platform/posix/FileSystemImpl.cpp
src/efsw/platform/posix/MutexImpl.cpp
src/efsw/platform/posix/SystemImpl.cpp
src/efsw/platform/posix/ThreadImpl.cpp)
endif()

if (WIN32)
list(APPEND SRCS
src/efsw/WatcherWin32.cpp
src/efsw/FileWatcherWin32.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
list(APPEND SRCS
src/efsw/FileWatcherInotify.cpp
src/efsw/WatcherInotify.cpp)

if (NOT EXISTS "/usr/include/sys/inotify.h" AND NOT EXISTS "/usr/local/include/sys/inotify.h")
add_definitions(-DEFSW_INOTIFY_NOSYS)
endif()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR APPLE)
list(APPEND SRCS
src/efsw/FileWatcherKqueue.cpp
src/efsw/WatcherKqueue.cpp)

if (APPLE)
list(APPEND SRCS
src/efsw/FileWatcherFSEvents.cpp
src/efsw/WatcherFSEvents.cpp)

exec_program(uname ARGS -v OUTPUT_VARIABLE OSX_VERSION)
string(REGEX MATCH "[0-9]+" OSX_VERSION ${OSX_VERSION})
if (NOT OSX_VERSION GREATER 9)
add_definitions(-DEFSW_FSEVENTS_NOT_SUPPORTED)
endif()

set(OPTIONAL_MAC_LINK_LIBRARIES "-framework CoreFoundation" "-framework CoreServices")
endif()
endif()

add_library(efsw STATIC ${SRCS})

target_include_directories(efsw
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src)

target_link_libraries(efsw
PUBLIC
threads
${OPTIONAL_MAC_LINK_LIBRARIES})

set_target_properties(efsw
PROPERTIES
FOLDER
"dep")
else()
add_library(efsw INTERFACE)
endif()
22 changes: 22 additions & 0 deletions dep/efsw/LICENSE
@@ -0,0 +1,22 @@
Copyright (c) 2012 Martín Lucas Golini

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com)
http://code.google.com/p/simplefilewatcher/ also MIT licensed.
138 changes: 138 additions & 0 deletions dep/efsw/README.md
@@ -0,0 +1,138 @@
Entropia File System Watcher
============================
**efsw** is a C++ cross-platform file system watcher and notifier.

**efsw** monitors the file system asynchronously for changes to files and directories by watching a list of specified paths, and raises events when a directory or file change.

**efsw** supports recursive directories watch, tracking the entire sub directory tree.

**efsw** currently supports the following platforms:

* Linux via [inotify](http://en.wikipedia.org/wiki/Inotify)

* Windows via [I/O Completion Ports](http://en.wikipedia.org/wiki/IOCP)

* Mac OS X via [FSEvents](http://en.wikipedia.org/wiki/FSEvents) or [kqueue](http://en.wikipedia.org/wiki/Kqueue)

* FreeBSD/BSD via [kqueue](http://en.wikipedia.org/wiki/Kqueue)

* OS-independent generic watcher
(polling the disk for directory snapshots and comparing them periodically)

If any of the backend fails to start by any reason, it will fallback to the OS-independent implementation.
This should never happen, except for the Kqueue implementation, see `Platform limitations and clarifications`.

**Code License**
--------------
[MIT License](http://www.opensource.org/licenses/mit-license.php)

**Some example code:**
--------------------

:::c++
// Inherits from the abstract listener class, and implements the the file action handler
class UpdateListener : public efsw::FileWatchListener
{
public:
UpdateListener() {}

void handleFileAction( efsw::WatchID watchid, const std::string& dir, const std::string& filename, efsw::Action action, std::string oldFilename = "" )
{
switch( action )
{
case efsw::Actions::Add:
std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Added" << std::endl;
break;
case efsw::Actions::Delete:
std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Delete" << std::endl;
break;
case efsw::Actions::Modified:
std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Modified" << std::endl;
break;
case efsw::Actions::Moved:
std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Moved from (" << oldFilename << ")" << std::endl;
break;
default:
std::cout << "Should never happen!" << std::endl;
}
}
};

// Create the file system watcher instance
// efsw::FileWatcher allow a first boolean parameter that indicates if it should start with the generic file watcher instead of the platform specific backend
efsw::FileWatcher * fileWatcher = new efsw::FileWatcher();

// Create the instance of your efsw::FileWatcherListener implementation
UpdateListener * listener = new UpdateListener();

// Add a folder to watch, and get the efsw::WatchID
// It will watch the /tmp folder recursively ( the third parameter indicates that is recursive )
// Reporting the files and directories changes to the instance of the listener
efsw::WatchID watchID = fileWatcher->addWatch( "/tmp", listener, true );

// Adds another directory to watch. This time as non-recursive.
efsw::WatchID watchID2 = fileWatcher->addWatch( "/usr", listener, false );

// Start watching asynchronously the directories
fileWatcher.watch();

// Remove the second watcher added
// You can also call removeWatch by passing the watch path ( it must end with an slash or backslash in windows, since that's how internally it's saved )
fileWatcher->removeWatch( watchID2 );

**Dependencies**
--------------
None :)

**Compiling**
------------
To generate project files you will need to [download and install](http://industriousone.com/premake/download) [Premake](http://industriousone.com/what-premake)

Then you can generate the project for your platform just going to the project directory where the premake4.lua file is located and then execute:

`premake4 gmake` to generate project Makefiles, then `cd make/*YOURPLATFORM*/`, and finally `make` or `make config=release` ( it will generate the static lib, the shared lib and the test application ).

or

`premake4 vs2010` to generate Visual Studio 2010 project.

or

`premake4 xcode4` to generate Xcode 4 project.

There is also a cmake file that i don't oficially support but it works just fine, provided by [Mohammed Nafees](https://bitbucket.org/binaryking).

**Platform limitations and clarifications**
-------------------------------------------

Directory paths are expected to be encoded as UTF-8 strings in all platforms.

handleFileAction returns UTF-8 strings in all platforms.

Windows and FSEvents Mac OS X implementation can't follow symlinks ( it will ignore followSymlinks() and allowOutOfScopeLinks() ).

Kqueue implementation is limited by the maximun number of file descriptors allowed per process by the OS, in the case of reaching the file descriptors limit ( in BSD around 18000 and in OS X around 10240 ) it will fallback to the generic file watcher.

OS X will only use Kqueue if OS X version is below to 10.5, and this implementation needs to be compiled separately from the OS X >= 10.5 implementation. Since there's no way to compile FSEvents backend in OS X below 10.5.

FSEvents for OS X Lion and beyond in some cases will generate more actions that in reality ocurred, since fine-grained implementation of FSEvents doesn't give the order of the actions retrieved, in some cases i need to guess/aproximate the order of them.

Generic watcher relies on the inode information to detect file and directories renames/move. Since Windows has no concept of inodes as Unix platforms do, there is no current reliable way of determining file/directory movement on Windows without help from the Windows API ( this is replaced with Add/Delete events ).

Linux versions below 2.6.13 are not supported, since inotify wasn't implemented yet. I'm not interested in support older kernels, since i don't see the point. If someone needs this open an issue in the issue tracker and i may consider implenent a dnotify backend.

OS-independent watcher, Kqueue and FSEvents for OS X below 10.5 keep cache of the directories structures, to be able to detect changes in the directories. This means that there's a memory overhead for this backends.

**Useful information**
--------------------
The project also comes with a C API wrapper, contributed by [Sepul Sepehr Taghdisian](https://bitbucket.org/sepul).

There's a string manipulation class not exposed in the efsw header ( efsw::String ) that can be used to make string encoding conversion.


**Clarifications**
----------------

This software started as a fork of the [simplefilewatcher](http://code.google.com/p/simplefilewatcher/) by James Wynn (james[at]jameswynn.com), [MIT licensed](http://www.opensource.org/licenses/mit-license.html).

The icon used for the project is part of the [Haiku®'s Icons](http://www.haiku-inc.org/haiku-icons.html), [MIT licensed](http://www.opensource.org/licenses/mit-license.html).

0 comments on commit 46daaf7

Please sign in to comment.