Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ private sealed class INotify
private readonly SafeFileHandle _inotifyHandle;
private readonly ConcurrentDictionary<int, Watch> _wdToWatch = new ConcurrentDictionary<int, Watch>();
private readonly ReaderWriterLockSlim _addLock = new(LockRecursionPolicy.NoRecursion);
private readonly ManualResetEventSlim _readyToRead = new(false);
private bool _isThreadStopping;
private bool _allWatchersStopped;
private int _bufferAvailable;
Expand Down Expand Up @@ -200,6 +201,11 @@ private void StartThread()
}
}

/// <summary>
/// Waits until the processing thread is ready to read inotify events.
/// </summary>
internal void WaitForReadReady() => _readyToRead.Wait();

private void StopINotify()
{
// This method gets called only on the ProcessEvents thread, or when that thread fails to start.
Expand Down Expand Up @@ -489,6 +495,11 @@ private void ProcessEvents()
uint movedFromCookie = 0;
bool movedFromIsDir = false;

// Signal that the processing thread is ready to read events.
// This ensures callers of Start() can wait until events will
// be captured before performing filesystem operations.
_readyToRead.Set();

while (TryReadEvent(out NotifyEvent nextEvent))
{
if (!ProcessEvent(nextEvent, ref movedFromWatchCount, ref movedFromName, ref movedFromCookie, ref movedFromIsDir))
Expand All @@ -509,6 +520,9 @@ private void ProcessEvents()
}
finally
{
// Ensure any caller blocked on WaitForReadReady() is unblocked,
// even if ProcessEvents exits early due to an error.
_readyToRead.Set();
Debug.Assert(_inotifyHandle.IsClosed);
}
}
Expand Down Expand Up @@ -1055,6 +1069,12 @@ public void Start()
}
}

// Ensure the processing thread is ready to read events before
// we start emitting or performing filesystem operations that
// should be observed. Without this, events can be missed if
// they occur before ProcessEvents enters its read loop.
inotify.WaitForReadReady();

_ = DequeueEvents();

if (rootDirectory is not null && IncludeSubdirectories)
Expand Down
Loading