SpartanJ / efsw

efsw is a C++ cross-platform file system watcher and notifier.
Other
662 stars 101 forks source link

Monitor multiple files failures under Windows #142

Closed huyi51462 closed 1 year ago

huyi51462 commented 2 years ago

I monitor a directory named "d:\A". There is another folder path "d:\B" which has 1000 files, each file is about 200kb. Copy folder B to folder A, the callback function works normally at first, but about halfway through, iocp no longer wakes up the child thread, the child thread is hangs in GetQueuedCompletionStatus(), and there is no response. What went wrong? Is it not possible to monitor files over a certain number or size?

huyi51462 commented 2 years ago

When you first call ReadDirectoryChangesW, the system allocates a buffer to store change information. This buffer is associated with the directory handle until it is closed and its size does not change during its lifetime. Directory changes that occur between calls to this function are added to the buffer and then returned with the next call. If the buffer overflows, ReadDirectoryChangesW will still return true, but the entire contents of the buffer are discarded and the lpBytesReturned parameter will be zero, which indicates that your buffer was too small to hold all of the changes that occurred.

The buffer is too small for changes that need to monitor a large number of files.

SpartanJ commented 2 years ago

The buffer size was limited because of an old Windows bug, at least that's what it says in the code: https://github.com/SpartanJ/efsw/blob/b60a4e6eff88999e122a50b33dbdf61a97bc5969/src/efsw/WatcherWin32.hpp#L62 I can probably increase the buffer size. I will take a look at this issue. Here are some remarks in the documentation: https://docs.microsoft.com/en-gb/windows/win32/api/winbase/nf-winbase-readdirectorychangesw?redirectedfrom=MSDN#remarks

huyi51462 commented 2 years ago

The buffer size was limited because of an old Windows bug, at least that's what it says in the code: I can probably increase the buffer size.

Yes, what occupies this buffer is actually the string of the file path,so in the case of a large number of files or many long path files, 64k is too small.

solarispika commented 1 year ago

In the current implementation, it seems impossible to determine whether the ReadDirectoryChangesW() call has failed or not. Is it possible to provide users with information about any failures, so they can react accordingly? Another suggestion could be to allow users to specify the buffer size or provide the buffer themselves, enabling them to tailor it to their needs. In this way, the onus is on the users to customize the buffer as necessary.

SpartanJ commented 1 year ago

That's a totally reasonable request. I've got to think of a good API for that and make it as a non-breaking change. If you have some minutes can you open a ticket for this specific feature request? Thanks

SpartanJ commented 1 year ago

This issues has been fixes thanks to the @r00tcxx contribution in this PR. :)