Skip to content

Commit

Permalink
Merge pull request #79 from napframework/filewatcher_linux_fix
Browse files Browse the repository at this point in the history
fix for not hot reloading when editing files in sub directories of the data folder on linux
  • Loading branch information
cklosters authored Feb 13, 2025
2 parents ae7b693 + a1d7959 commit 9ac24ff
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 10 deletions.
81 changes: 72 additions & 9 deletions core/src/nap/linux/FileWatcher/FileWatcherLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,53 @@

#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <cstring>
#include <cstdio>
#include <cerrno>
#include <unistd.h>
#include <sys/inotify.h>

#include <sys/types.h>
#include <dirent.h>

#define BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)

namespace FW
{
/**
* Utility function to list all subdirectories of a given directory
* @param directoryPath absolute path of root directory
* @param dirs vector filled with absolute paths of subdirectories
*/
static void listSubdirectories(const std::string &directoryPath, std::vector<std::string>& dirs)
{
DIR *dir = opendir(directoryPath.c_str());
if (dir == nullptr)
return;

struct dirent *entry;
while ((entry = readdir(dir)) != nullptr)
{
// Skip the '.' and '..' directories
if (entry->d_name[0] == '.')
continue;

// Get information about the directory entry
struct stat statbuf;
std::string fullPath = directoryPath + "/" + entry->d_name;
if (stat(fullPath.c_str(), &statbuf) == 0)
{
// Check if it's a directory
if (S_ISDIR(statbuf.st_mode))
{
dirs.emplace_back(fullPath);
listSubdirectories(fullPath, dirs);
}
}
}
closedir(dir);
}


struct WatchStruct
{
Expand Down Expand Up @@ -82,9 +119,6 @@ namespace FW
throw FileNotFoundException(directory);
else
throw Exception(strerror(errno));

// fprintf (stderr, "Error: %s\n", strerror(errno));
// return -1;
}

WatchStruct* pWatch = new WatchStruct();
Expand All @@ -93,7 +127,22 @@ namespace FW
pWatch->mDirName = directory;

mWatches.insert(std::make_pair(wd, pWatch));


// create watches for subdirectories
// when recursive is true watches will be added that watch each subdirectories
// the watches are stored in a map so they can be removed when the root watch is removed
// a root watch is a watch that was added with the recursive option set to true
if (recursive)
{
// obtain a list of all subdirectories
std::vector<std::string> dirs;
listSubdirectories(directory, dirs);

// add watches for each subdirectory
for (const auto& dir : dirs)
mSubDirWatches[wd].emplace_back(addWatch(dir, watcher, false));
}

return wd;
}

Expand All @@ -106,7 +155,10 @@ namespace FW
{
if(directory == iter->second->mDirName)
{
removeWatch(iter->first);
// remove watch
WatchID wd = iter->first;
removeWatch(wd);

return;
}
}
Expand All @@ -127,6 +179,16 @@ namespace FW

delete watch;
watch = 0;

// remove watches for subdirectories if those were added with the root watch
auto it = mSubDirWatches.find(watchid);
if (it != mSubDirWatches.end())
{
for (const auto& subDirWatch : it->second)
removeWatch(subDirWatch);

mSubDirWatches.erase(it);
}
}

//--------
Expand Down Expand Up @@ -180,7 +242,8 @@ namespace FW
Actions::Delete);
}
}

};//namespace FW



#endif//FILEWATCHER_PLATFORM_LINUX
6 changes: 6 additions & 0 deletions core/src/nap/linux/FileWatcher/FileWatcherLinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

#include <map>
#include <sys/types.h>
#include <vector>
#include <unordered_map>

namespace FW
{
Expand Down Expand Up @@ -82,6 +84,10 @@ namespace FW
/// File descriptor set
fd_set mDescriptorSet;

/// Stores watches for subdirectories that were added with addWatch with the recursive option set to true
/// The key is the watchid of the root watch
std::unordered_map<WatchID, std::vector<WatchID>> mSubDirWatches;

};//end FileWatcherLinux

};//namespace FW
Expand Down
1 change: 0 additions & 1 deletion core/src/nap/resourcemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ namespace nap
mRollbackObjects = false;
}


void ResourceManager::RollbackHelper::addExistingDevice(Device& device)
{
mExistingDevices.push_back(&device);
Expand Down

6 comments on commit 9ac24ff

@cklosters
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity Public / Package NAP Win64 Build 342 is now running

@cklosters
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity Public / Package NAP Raspberry Pi Build 1820 is now running

@cklosters
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity Public / Package NAP Linux Build 334 is now running

@cklosters
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity Public / Package NAP Win64 Build 342 outcome was SUCCESS
Summary: Running Build time: 00:04:20

@cklosters
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity Public / Package NAP Linux Build 334 outcome was SUCCESS
Summary: Running Build time: 00:32:05

@cklosters
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TeamCity Public / Package NAP Raspberry Pi Build 1820 outcome was SUCCESS
Summary: Running Build time: 00:45:03

Please sign in to comment.