diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-01-08 11:41:33 -0800 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2020-01-08 11:41:33 -0800 |
commit | 35b56cdce57d88897cf486cd9dca25503c20f140 (patch) | |
tree | 840bdc8ae581564b91d1a78f91e082e4cf9e32e4 | |
parent | 9c7511e33c0c41e692964c11c613bbff0fb35516 (diff) | |
download | psutil-35b56cdce57d88897cf486cd9dca25503c20f140.tar.gz |
progress with thread skeleton
-rw-r--r-- | psutil/arch/windows/process_handles.c | 221 |
1 files changed, 41 insertions, 180 deletions
diff --git a/psutil/arch/windows/process_handles.c b/psutil/arch/windows/process_handles.c index ee593d10..57edb66d 100644 --- a/psutil/arch/windows/process_handles.c +++ b/psutil/arch/windows/process_handles.c @@ -12,84 +12,71 @@ #include "process_utils.h" +// Global objects used by threads. CRITICAL_SECTION g_cs; BOOL g_initialized = FALSE; NTSTATUS g_status; HANDLE g_hFile = NULL; -HANDLE g_hEvtStart = NULL; -HANDLE g_hEvtFinish = NULL; -HANDLE g_hThread = NULL; PUNICODE_STRING g_pNameBuffer = NULL; ULONG g_dwSize = 0; ULONG g_dwLength = 0; -#define NTQO_TIMEOUT 100 +#define NTQO_TIMEOUT 2000 #define MALLOC_ZERO(x) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)) -static VOID +static DWORD psutil_init_threads() { if (g_initialized == TRUE) - return; - - // Create events for signalling work between threads - g_hEvtStart = CreateEvent(NULL, FALSE, FALSE, NULL); - g_hEvtFinish = CreateEvent(NULL, FALSE, FALSE, NULL); + return 0; InitializeCriticalSection(&g_cs); g_initialized = TRUE; + return 0; } -static DWORD WINAPI -psutil_wait_thread(LPVOID lpvParam) { - // Loop infinitely waiting for work - while (TRUE) { - WaitForSingleObject(g_hEvtStart, INFINITE); - - // TODO: return code not checked - g_status = NtQueryObject( - g_hFile, - ObjectNameInformation, - g_pNameBuffer, - g_dwSize, - &g_dwLength); - SetEvent(g_hEvtFinish); - } +static int +psutil_get_filename(LPVOID lpvParam) { + printf("inside thread fun\n"); + // Sleep(3000); + return 0; } static DWORD psutil_create_thread() { DWORD dwWait = 0; + HANDLE hThread = NULL; + DWORD threadRetValue; - if (g_hThread == NULL) - g_hThread = CreateThread( - NULL, - 0, - psutil_wait_thread, - NULL, - 0, - NULL); - if (g_hThread == NULL) - return GetLastError(); - - // Signal the worker thread to start - SetEvent(g_hEvtStart); + hThread = CreateThread(NULL, 0, psutil_get_filename, NULL, 0, NULL); + if (hThread == NULL) { + PyErr_SetFromOSErrnoWithSyscall("CreateThread"); + return 1; + } // Wait for the worker thread to finish - dwWait = WaitForSingleObject(g_hEvtFinish, NTQO_TIMEOUT); + dwWait = WaitForSingleObject(hThread, NTQO_TIMEOUT); - // If the thread hangs, kill it and cleanup + // If the thread hangs, kill it and cleanup. if (dwWait == WAIT_TIMEOUT) { - SuspendThread(g_hThread); - TerminateThread(g_hThread, 1); - WaitForSingleObject(g_hThread, INFINITE); - CloseHandle(g_hThread); - - g_hThread = NULL; + printf("thread timed out\n"); + SuspendThread(hThread); + TerminateThread(hThread, 1); + CloseHandle(hThread); + return 0; + } + else { + printf("thread completed\n"); + if (GetExitCodeThread(hThread, &threadRetValue) == 0) { + CloseHandle(hThread); + PyErr_SetFromOSErrnoWithSyscall("GetExitCodeThread"); + return 1; + } + CloseHandle(hThread); + printf("retcode = %i\n", threadRetValue); + return threadRetValue; } - - return dwWait; } @@ -152,7 +139,12 @@ psutil_get_open_files(DWORD dwPid, HANDLE hProcess) { return NULL; if (g_initialized == FALSE) - psutil_init_threads(); + if (psutil_init_threads() != 0) + goto error; + + ret = psutil_create_thread(); + if (ret != 0) + goto error; goto exit; @@ -167,134 +159,3 @@ exit: return py_retlist; } - -/* - if (g_initialized == FALSE) - psutil_get_open_files_init(TRUE); - - // Due to the use of global variables, ensure only 1 call - // to psutil_get_open_files() is running - EnterCriticalSection(&g_cs); - - if (g_hEvtStart == NULL || g_hEvtFinish == NULL) { - PyErr_SetFromWindowsErr(0); - error = TRUE; - goto cleanup; - } - - // Py_BuildValue raises an exception if NULL is returned - py_retlist = PyList_New(0); - if (py_retlist == NULL) { - error = TRUE; - goto cleanup; - } - - ret = psutil_enum_handles(&handlesList); - if (ret != 0) - goto cleanup; - - for (i = 0; i < handlesList->NumberOfHandles; i++) { - hHandle = &handlesList->Handles[i]; - - // Check if this hHandle belongs to the PID the user specified. - if ((ULONG_PTR)hHandle->UniqueProcessId != dwPid) - goto loop_cleanup; - - if (!DuplicateHandle(hProcess, - (HANDLE)hHandle->HandleValue, - GetCurrentProcess(), - &g_hFile, - 0, - TRUE, - DUPLICATE_SAME_ACCESS)) - { - goto loop_cleanup; - } - - // Guess buffer size is MAX_PATH + 1 - g_dwLength = (MAX_PATH+1) * sizeof(WCHAR); - - do { - // Release any previously allocated buffer - if (g_pNameBuffer != NULL) { - FREE(g_pNameBuffer); - g_pNameBuffer = NULL; - g_dwSize = 0; - } - - // NtQueryObject puts the required buffer size in g_dwLength - // WinXP edge case puts g_dwLength == 0, just skip this handle - if (g_dwLength == 0) - goto loop_cleanup; - - g_dwSize = g_dwLength; - if (g_dwSize > 0) { - g_pNameBuffer = malloc(g_dwSize); - - if (g_pNameBuffer == NULL) - goto loop_cleanup; - } - - dwWait = psutil_create_thread(); - - // If the call does not return, skip this handle - if (dwWait != WAIT_OBJECT_0) - goto loop_cleanup; - - } while (g_status == STATUS_INFO_LENGTH_MISMATCH); - - // NtQueryObject stopped returning STATUS_INFO_LENGTH_MISMATCH - if (!NT_SUCCESS(g_status)) - goto loop_cleanup; - - // Convert to PyUnicode and append it to the return list - if (g_pNameBuffer->Length > 0) { - py_path = PyUnicode_FromWideChar(g_pNameBuffer->Buffer, - g_pNameBuffer->Length / 2); - if (py_path == NULL) { - error = TRUE; - goto loop_cleanup; - } - - if (PyList_Append(py_retlist, py_path)) { - error = TRUE; - goto loop_cleanup; - } - } - -loop_cleanup: - Py_XDECREF(py_path); - py_path = NULL; - if (g_pNameBuffer != NULL) - FREE(g_pNameBuffer); - g_pNameBuffer = NULL; - g_dwSize = 0; - g_dwLength = 0; - if (g_hFile != NULL) - CloseHandle(g_hFile); - g_hFile = NULL; -} - -cleanup: - if (g_pNameBuffer != NULL) - FREE(g_pNameBuffer); - g_pNameBuffer = NULL; - g_dwSize = 0; - g_dwLength = 0; - - if (g_hFile != NULL) - CloseHandle(g_hFile); - g_hFile = NULL; - - if (handlesList != NULL) - FREE(handlesList); - handlesList = NULL; - - if (error) { - Py_XDECREF(py_retlist); - py_retlist = NULL; - } - - LeaveCriticalSection(&g_cs); - return py_retlist; -*/ |