From 6ee4285588019c9842e221cd627f6627cf8ac2fa Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 10 Feb 2020 12:00:15 -0500 Subject: close handles in thread --- src/envfs.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/envfs.cpp b/src/envfs.cpp index cb2764ae..81a0d3ef 100644 --- a/src/envfs.cpp +++ b/src/envfs.cpp @@ -4,16 +4,6 @@ using namespace MOBase; -struct NtCloser -{ - using pointer = HANDLE; - void operator()(HANDLE h) - { - } -}; - -using NtHandle = std::unique_ptr; - typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; @@ -76,8 +66,12 @@ typedef NTSTATUS(WINAPI *NtOpenFile_type)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG); +typedef NTSTATUS(WINAPI *NtClose_type)(HANDLE); + + NtOpenFile_type NtOpenFile = nullptr; NtQueryDirectoryFile_type NtQueryDirectoryFile = nullptr; +extern NtClose_type NtClose = nullptr; #define FILE_DIRECTORY_FILE 0x00000001 @@ -160,9 +154,40 @@ constexpr std::size_t AllocSize = 1024 * 1024; std::vector> g_buffers; +struct HandleCloserThread +{ + std::vector handles; + std::thread thread; + std::atomic busy; + + HandleCloserThread() + : busy(false) + { + } + + ~HandleCloserThread() + { + if (thread.joinable()) { + thread.join(); + } + } + + void closeHandles() + { + for (auto& h : handles) { + NtClose(h); + } + + handles.clear(); + busy = false; + } +}; + +std::array g_handleCloserThreads; + void forEachEntryImpl( - void* cx, POBJECT_ATTRIBUTES poa, std::size_t depth, + void* cx, HandleCloserThread& hc, POBJECT_ATTRIBUTES poa, std::size_t depth, DirStartF* dirStartF, DirEndF* dirEndF, FileF* fileF) { IO_STATUS_BLOCK iosb; @@ -170,8 +195,6 @@ void forEachEntryImpl( OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName }; NTSTATUS status; - //log::debug("{}{}", std::wstring(depth * 2, L' '), toString(poa)); - status = NtOpenFile( &oa.RootDirectory, FILE_GENERIC_READ, poa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT); @@ -184,10 +207,7 @@ void forEachEntryImpl( return; } - NtHandle rootDirectoryHandle(oa.RootDirectory); - - //std::unique_ptr buffer(new unsigned char[AllocSize]); - + hc.handles.push_back(oa.RootDirectory); unsigned char* buffer; if (depth >= g_buffers.size()) { @@ -248,7 +268,7 @@ void forEachEntryImpl( if (DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { dirStartF(cx, toStringView(&oa)); - forEachEntryImpl(cx, &oa, depth+1, dirStartF, dirEndF, fileF); + forEachEntryImpl(cx, hc, &oa, depth+1, dirStartF, dirEndF, fileF); dirEndF(cx, toStringView(&oa)); } else { //log::debug("{}{}", std::wstring((depth + 1) * 2, L' '), toString(&oa)); @@ -266,8 +286,6 @@ void forEachEntryImpl( } } - //log::debug("{}{} processed {} files", std::wstring(depth * 2, L' '), toString(poa), count); - if (AllocSize - iosb.Information > (ULONG)FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName[256])) { // NO_MORE_FILES break; @@ -275,14 +293,41 @@ void forEachEntryImpl( } } +std::size_t findHandleCloserThread() +{ + for (;;) { + for (std::size_t i=0; i