mirror of
https://github.com/winfsp/winfsp.git
synced 2026-06-24 21:42:33 -05:00
tst: notify_rename_race_test: repro notify/rename deadlock
This commit is contained in:
@@ -474,6 +474,95 @@ void notify_dirnotify_test(void)
|
||||
}
|
||||
}
|
||||
|
||||
struct notify_rename_race_params
|
||||
{
|
||||
WCHAR Src[MAX_PATH];
|
||||
WCHAR Dst[MAX_PATH];
|
||||
HANDLE StartEvent;
|
||||
};
|
||||
|
||||
static
|
||||
unsigned __stdcall notify_rename_race_dotest_thread(void *Params0)
|
||||
{
|
||||
struct notify_rename_race_params *Params = Params0;
|
||||
|
||||
WaitForSingleObject(Params->StartEvent, INFINITE);
|
||||
|
||||
BOOL Success = MoveFileExW(Params->Src, Params->Dst, 0);
|
||||
|
||||
return Success ? 0 : GetLastError();
|
||||
}
|
||||
|
||||
static
|
||||
void notify_rename_race_dotest(ULONG Flags, PWSTR Prefix)
|
||||
{
|
||||
void *memfs = memfs_start(Flags);
|
||||
FSP_FILE_SYSTEM *FileSystem = MemfsFileSystem(memfs);
|
||||
union
|
||||
{
|
||||
FSP_FSCTL_NOTIFY_INFO V;
|
||||
UINT8 B[sizeof(FSP_FSCTL_NOTIFY_INFO) + 2 * sizeof(WCHAR)];
|
||||
} NotifyInfo;
|
||||
struct notify_rename_race_params Params;
|
||||
HANDLE Thread;
|
||||
DWORD ExitCode;
|
||||
NTSTATUS Result;
|
||||
HANDLE Handle;
|
||||
PWSTR FileName;
|
||||
|
||||
StringCbPrintfW(Params.Src, sizeof Params.Src, L"%s%s\\file0",
|
||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||
StringCbPrintfW(Params.Dst, sizeof Params.Dst, L"%s%s\\file0.new",
|
||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||
|
||||
Handle = CreateFileW(Params.Src,
|
||||
GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
||||
CloseHandle(Handle);
|
||||
|
||||
FileName = L"\\";
|
||||
NotifyInfo.V.Size = (UINT16)(sizeof(FSP_FSCTL_NOTIFY_INFO) + wcslen(FileName) * sizeof(WCHAR));
|
||||
NotifyInfo.V.Filter = FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
NotifyInfo.V.Action = FILE_ACTION_MODIFIED;
|
||||
memcpy(NotifyInfo.V.FileNameBuf, FileName, NotifyInfo.V.Size - sizeof(FSP_FSCTL_NOTIFY_INFO));
|
||||
|
||||
Params.StartEvent = CreateEventW(0, TRUE, FALSE, 0);
|
||||
ASSERT(0 != Params.StartEvent);
|
||||
|
||||
Thread = (HANDLE)_beginthreadex(0, 0, notify_rename_race_dotest_thread, &Params, 0, 0);
|
||||
ASSERT(0 != Thread);
|
||||
|
||||
Result = FspFileSystemNotifyBegin(FileSystem, 1000);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
SetEvent(Params.StartEvent);
|
||||
Sleep(1000); /* wait for rename IRP to enter the kernel and block */
|
||||
|
||||
Result = FspFileSystemNotify(FileSystem, &NotifyInfo.V, NotifyInfo.V.Size);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
Result = FspFileSystemNotifyEnd(FileSystem);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
WaitForSingleObject(Thread, INFINITE);
|
||||
GetExitCodeThread(Thread, &ExitCode);
|
||||
CloseHandle(Thread);
|
||||
ASSERT(STATUS_SUCCESS == ExitCode);
|
||||
|
||||
CloseHandle(Params.StartEvent);
|
||||
|
||||
memfs_stop(memfs);
|
||||
}
|
||||
|
||||
static
|
||||
void notify_rename_race_test(void)
|
||||
{
|
||||
if (WinFspDiskTests)
|
||||
notify_rename_race_dotest(MemfsDisk, 0);
|
||||
if (WinFspNetTests)
|
||||
notify_rename_race_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||
}
|
||||
|
||||
void notify_tests(void)
|
||||
{
|
||||
if (OptExternal || OptNotify)
|
||||
@@ -489,4 +578,5 @@ void notify_tests(void)
|
||||
TEST(notify_change_test);
|
||||
TEST(notify_open_change_test);
|
||||
TEST(notify_dirnotify_test);
|
||||
TEST(notify_rename_race_test);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user