aboutsummaryrefslogtreecommitdiff
path: root/dep/efsw/src/efsw/FileWatcherWin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/efsw/src/efsw/FileWatcherWin32.cpp')
-rw-r--r--dep/efsw/src/efsw/FileWatcherWin32.cpp182
1 files changed, 102 insertions, 80 deletions
diff --git a/dep/efsw/src/efsw/FileWatcherWin32.cpp b/dep/efsw/src/efsw/FileWatcherWin32.cpp
index fe78dd122cf..317506fb3e3 100644
--- a/dep/efsw/src/efsw/FileWatcherWin32.cpp
+++ b/dep/efsw/src/efsw/FileWatcherWin32.cpp
@@ -2,6 +2,7 @@
#include <efsw/FileSystem.hpp>
#include <efsw/System.hpp>
#include <efsw/String.hpp>
+#include <efsw/Lock.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
@@ -18,23 +19,9 @@ FileWatcherWin32::FileWatcherWin32( FileWatcher * parent ) :
FileWatcherWin32::~FileWatcherWin32()
{
- WatchVector::iterator iter = mWatches.begin();
-
- mWatchesLock.lock();
-
- for(; iter != mWatches.end(); ++iter)
- {
- DestroyWatch((*iter));
- }
-
- mHandles.clear();
- mWatches.clear();
-
mInitOK = false;
-
- mWatchesLock.unlock();
-
efSAFE_DELETE( mThread );
+ removeAllWatches();
}
WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive)
@@ -54,9 +41,14 @@ WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListen
FileSystem::dirAddSlashAtEnd( dir );
- WatchID watchid = ++mLastWatchID;
+ Lock lock( mWatchesLock );
+
+ if ( pathInWatches( dir ) )
+ {
+ return Errors::Log::createLastError( Errors::FileRepeated, dir );
+ }
- mWatchesLock.lock();
+ WatchID watchid = ++mLastWatchID;
WatcherStructWin32 * watch = CreateWatch( String::fromUtf8( dir ).toWideString().c_str(), recursive, FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_LAST_WRITE |
@@ -70,11 +62,6 @@ WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListen
return Errors::Log::createLastError( Errors::FileNotFound, dir );
}
- if ( pathInWatches( dir ) )
- {
- return Errors::Log::createLastError( Errors::FileRepeated, dir );
- }
-
// Add the handle to the handles vector
watch->Watch->ID = watchid;
watch->Watch->Watch = this;
@@ -82,67 +69,81 @@ WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListen
watch->Watch->DirName = new char[dir.length()+1];
strcpy(watch->Watch->DirName, dir.c_str());
- mHandles.push_back( watch->Watch->DirHandle );
- mWatches.push_back( watch );
- mWatchesLock.unlock();
+ mWatchesNew.insert( watch );
+ mWatches.insert( watch );
return watchid;
}
void FileWatcherWin32::removeWatch(const std::string& directory)
{
- mWatchesLock.lock();
+ Lock lock( mWatchesLock );
- WatchVector::iterator iter = mWatches.begin();
+ Watches::iterator iter = mWatches.begin();
for(; iter != mWatches.end(); ++iter)
{
if(directory == (*iter)->Watch->DirName)
{
- removeWatch((*iter)->Watch->ID);
- return;
+ removeWatch(*iter);
+ break;
}
}
-
- mWatchesLock.unlock();
}
void FileWatcherWin32::removeWatch(WatchID watchid)
{
- mWatchesLock.lock();
-
- WatchVector::iterator iter = mWatches.begin();
+ Lock lock( mWatchesLock );
- WatcherStructWin32* watch = NULL;
+ Watches::iterator iter = mWatches.begin();
for(; iter != mWatches.end(); ++iter)
{
// Find the watch ID
if ( (*iter)->Watch->ID == watchid )
{
- watch = (*iter);
+ removeWatch(*iter);
+ return;
+ }
+ }
+}
- mWatches.erase( iter );
+void FileWatcherWin32::removeWatch(WatcherStructWin32* watch)
+{
+ mWatchesRemoved.insert(watch);
- // Remove handle from the handle vector
- HandleVector::iterator it = mHandles.begin();
+ if( NULL == mThread )
+ {
+ removeWatches();
+ }
+}
- for ( ; it != mHandles.end(); it++ )
- {
- if ( watch->Watch->DirHandle == (*it) )
- {
- mHandles.erase( it );
- break;
- }
- }
+void FileWatcherWin32::removeWatches()
+{
+ Lock lock( mWatchesLock );
- DestroyWatch(watch);
+ Watches::iterator remWatchIter = mWatchesRemoved.begin();
- break;
+ for( ; remWatchIter != mWatchesRemoved.end(); ++remWatchIter )
+ {
+ Watches::iterator iter = mWatches.find(*remWatchIter);
+
+ if( iter != mWatches.end() )
+ {
+ DestroyWatch(*iter);
+
+ mWatches.erase( iter );
+ }
+
+ iter = mWatchesNew.find(*remWatchIter);
+
+ if( iter != mWatchesNew.end() )
+ {
+ mWatchesNew.erase( iter );
}
}
- mWatchesLock.unlock();
+ mWatchesRemoved.clear();
}
void FileWatcherWin32::watch()
@@ -154,45 +155,47 @@ void FileWatcherWin32::watch()
}
}
-void FileWatcherWin32::run()
+void FileWatcherWin32::removeAllWatches()
{
- if ( mHandles.empty() )
+ Lock lock( mWatchesLock );
+
+ Watches::iterator iter = mWatches.begin();
+
+ for( ; iter != mWatches.end(); ++iter )
{
- return;
+ DestroyWatch((*iter));
}
+ mWatches.clear();
+ mWatchesRemoved.clear();
+ mWatchesNew.clear();
+}
+
+void FileWatcherWin32::run()
+{
do
{
- if ( !mHandles.empty() )
+ if ( !mWatches.empty() )
{
- mWatchesLock.lock();
-
- for ( std::size_t i = 0; i < mWatches.size(); i++ )
{
- WatcherStructWin32 * watch = mWatches[ i ];
-
- // If the overlapped struct was cancelled ( because the creator thread doesn't exists anymore ),
- // we recreate the overlapped in the current thread and refresh the watch
- if ( /*STATUS_CANCELED*/0xC0000120 == watch->Overlapped.Internal )
- {
- watch->Overlapped = OVERLAPPED();
- RefreshWatch(watch);
- }
+ Lock lock( mWatchesLock );
- // First ensure that the handle is the same, this means that the watch was not removed.
- if ( HasOverlappedIoCompleted( &watch->Overlapped ) && mHandles[ i ] == watch->Watch->DirHandle )
+ for( Watches::iterator iter = mWatches.begin() ; iter != mWatches.end(); ++iter )
{
- DWORD bytes;
+ WatcherStructWin32 * watch = *iter;
- if ( GetOverlappedResult( watch->Watch->DirHandle, &watch->Overlapped, &bytes, FALSE ) )
+ if ( HasOverlappedIoCompleted( &watch->Overlapped ) )
{
- WatchCallback( ERROR_SUCCESS, bytes, &watch->Overlapped );
+ DWORD bytes;
+
+ if ( GetOverlappedResult( watch->Watch->DirHandle, &watch->Overlapped, &bytes, FALSE ) )
+ {
+ WatchCallback( ERROR_SUCCESS, bytes, &watch->Overlapped );
+ }
}
}
}
- mWatchesLock.unlock();
-
if ( mInitOK )
{
System::sleep( 10 );
@@ -203,7 +206,18 @@ void FileWatcherWin32::run()
// Wait for a new handle to be added
System::sleep( 10 );
}
+
+ removeWatches();
+
+ for ( Watches::iterator it = mWatchesNew.begin(); it != mWatchesNew.end(); ++it )
+ {
+ RefreshWatch(*it);
+ }
+
+ mWatchesNew.clear();
} while ( mInitOK );
+
+ removeAllWatches();
}
void FileWatcherWin32::handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename)
@@ -232,7 +246,7 @@ void FileWatcherWin32::handleAction(Watcher* watch, const std::string& filename,
FileSystem::dirAddSlashAtEnd( opath );
FileSystem::dirAddSlashAtEnd( fpath );
- for ( WatchVector::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
+ for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
{
if ( (*it)->Watch->Directory == opath )
{
@@ -254,28 +268,36 @@ void FileWatcherWin32::handleAction(Watcher* watch, const std::string& filename,
break;
};
- watch->Listener->handleFileAction(watch->ID, static_cast<WatcherWin32*>( watch )->DirName, filename, fwAction);
+ std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
+ std::string realFilename = filename;
+ std::size_t sepPos = filename.find_last_of("/\\");
+
+ if ( sepPos != std::string::npos )
+ {
+ folderPath += filename.substr( 0, sepPos );
+ realFilename = filename.substr( sepPos + 1 );
+ }
+
+ watch->Listener->handleFileAction(watch->ID, folderPath, realFilename, fwAction);
}
std::list<std::string> FileWatcherWin32::directories()
{
std::list<std::string> dirs;
- mWatchesLock.lock();
+ Lock lock( mWatchesLock );
- for ( WatchVector::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
+ for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
{
dirs.push_back( std::string( (*it)->Watch->DirName ) );
}
- mWatchesLock.unlock();
-
return dirs;
}
bool FileWatcherWin32::pathInWatches( const std::string& path )
{
- for ( WatchVector::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
+ for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
{
if ( (*it)->Watch->DirName == path )
{