From 7dc11f26bf62a8b64c0f3442a23560f469ca6b2e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 8 Aug 2010 03:41:33 +0000 Subject: [PATCH] [TASKMGR] - Use messages instead of events to notify the update threads - Fixes a handle leak - Fix some typos - Patch by Carlo Bramini (carlo.bramix at libero dot it) See issue #3104 for more details. svn path=/trunk/; revision=48484 --- reactos/base/applications/taskmgr/applpage.c | 46 ++++++++----------- reactos/base/applications/taskmgr/debug.c | 2 +- reactos/base/applications/taskmgr/endproc.c | 2 +- reactos/base/applications/taskmgr/graph.c | 2 +- reactos/base/applications/taskmgr/graphctl.c | 4 +- reactos/base/applications/taskmgr/graphctl.h | 2 +- reactos/base/applications/taskmgr/optnmenu.c | 4 +- reactos/base/applications/taskmgr/perfdata.c | 2 +- reactos/base/applications/taskmgr/perfpage.c | 46 +++++++------------ reactos/base/applications/taskmgr/procpage.c | 47 +++++++------------- reactos/base/applications/taskmgr/taskmgr.c | 31 ++++++++++--- reactos/base/applications/taskmgr/taskmgr.h | 2 +- 12 files changed, 87 insertions(+), 103 deletions(-) diff --git a/reactos/base/applications/taskmgr/applpage.c b/reactos/base/applications/taskmgr/applpage.c index 0c20e810817..88c52070fa9 100644 --- a/reactos/base/applications/taskmgr/applpage.c +++ b/reactos/base/applications/taskmgr/applpage.c @@ -38,7 +38,6 @@ HWND hApplicationPageSwitchToButton; /* Application Switch To button HWND hApplicationPageNewTaskButton; /* Application New Task button */ static int nApplicationPageWidth; static int nApplicationPageHeight; -static HANDLE hApplicationPageEvent = NULL; /* When this event becomes signaled then we refresh the app list */ static BOOL bSortAscending = TRUE; DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter); BOOL noApps; @@ -51,6 +50,11 @@ void ApplicationPageShowContextMenu2(void); int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); int ProcGetIndexByProcessId(DWORD dwProcessId); +#ifdef RUN_APPS_PAGE +static HANDLE hApplicationThread = NULL; +static DWORD dwApplicationThread; +#endif + #if 0 void SwitchToThisWindow ( HWND hWnd, /* Handle to the window that should be activated */ @@ -92,7 +96,6 @@ ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) LV_COLUMN column; WCHAR szTemp[256]; int cx, cy; - HANDLE hRefreshThread = NULL; switch (message) { case WM_INITDIALOG: @@ -132,15 +135,16 @@ ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) UpdateApplicationListControlViewSetting(); /* Start our refresh thread */ - hRefreshThread = CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, NULL); - +#ifdef RUN_APPS_PAGE + hApplicationThread = CreateThread(NULL, 0, ApplicationPageRefreshThread, NULL, 0, &dwApplicationThread); +#endif return TRUE; case WM_DESTROY: - /* Close the event handle, this will make the */ - /* refresh thread exit when the wait fails */ - CloseHandle(hApplicationPageEvent); - CloseHandle(hRefreshThread); + /* Close refresh thread */ +#ifdef RUN_APPS_PAGE + EndLocalThread(&hApplicationThread, dwApplicationThread); +#endif break; case WM_COMMAND: @@ -213,9 +217,11 @@ ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) void RefreshApplicationPage(void) { +#ifdef RUN_APPS_PAGE /* Signal the event so that our refresh thread */ /* will wake up and refresh the application page */ - SetEvent(hApplicationPageEvent); + PostThreadMessage(dwApplicationThread, WM_TIMER, 0, 0); +#endif } void UpdateApplicationListControlViewSetting(void) @@ -236,6 +242,7 @@ void UpdateApplicationListControlViewSetting(void) DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter) { + MSG msg; INT i; BOOL bItemRemoved = FALSE; LV_ITEM item; @@ -243,30 +250,15 @@ DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter) HIMAGELIST hImageListLarge; HIMAGELIST hImageListSmall; - /* Create the event */ - hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL); - /* If we couldn't create the event then exit the thread */ - if (!hApplicationPageEvent) - return 0; - while (1) { - DWORD dwWaitVal; - - /* Wait on the event */ - dwWaitVal = WaitForSingleObject(hApplicationPageEvent, INFINITE); - - /* If the wait failed then the event object must have been */ - /* closed and the task manager is exiting so exit this thread */ - if (dwWaitVal == WAIT_FAILED) + /* Wait for an the event or application close */ + if (GetMessage(&msg, NULL, 0, 0) <= 0) return 0; - if (dwWaitVal == WAIT_OBJECT_0) + if (msg.message == WM_TIMER) { - /* Reset our event */ - ResetEvent(hApplicationPageEvent); - /* * FIXME: * diff --git a/reactos/base/applications/taskmgr/debug.c b/reactos/base/applications/taskmgr/debug.c index fb11fc73fec..f72ba26a03d 100644 --- a/reactos/base/applications/taskmgr/debug.c +++ b/reactos/base/applications/taskmgr/debug.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * debug.cpp + * debug.c * * Copyright (C) 1999 - 2001 Brian Palmer * 2005 Klemens Friedl diff --git a/reactos/base/applications/taskmgr/endproc.c b/reactos/base/applications/taskmgr/endproc.c index 3ae716f568c..be080ffbddf 100644 --- a/reactos/base/applications/taskmgr/endproc.c +++ b/reactos/base/applications/taskmgr/endproc.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * endproc.cpp + * endproc.c * * Copyright (C) 1999 - 2001 Brian Palmer * 2005 Klemens Friedl diff --git a/reactos/base/applications/taskmgr/graph.c b/reactos/base/applications/taskmgr/graph.c index 6045a8f218f..b7b937e388c 100644 --- a/reactos/base/applications/taskmgr/graph.c +++ b/reactos/base/applications/taskmgr/graph.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * graph.cpp + * graph.c * * Copyright (C) 1999 - 2001 Brian Palmer * diff --git a/reactos/base/applications/taskmgr/graphctl.c b/reactos/base/applications/taskmgr/graphctl.c index a1abf779e5a..5735e8b4d8d 100644 --- a/reactos/base/applications/taskmgr/graphctl.c +++ b/reactos/base/applications/taskmgr/graphctl.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * GraphCtrl.cpp + * graphctl.c * * Copyright (C) 2002 Robert Dickenson * @@ -425,7 +425,7 @@ void GraphCtrl_DrawPoint(TGraphCtrl* this) * note: the m_dcPlot covers the entire client * but we only shift bitmap that is the size * of the plot rectangle - * grab the right side of the plot (exluding m_nShiftPixels on the left) + * grab the right side of the plot (excluding m_nShiftPixels on the left) * move this grabbed bitmap to the left by m_nShiftPixels */ BitBlt(this->m_dcPlot, this->m_rectPlot.left, this->m_rectPlot.top+1, diff --git a/reactos/base/applications/taskmgr/graphctl.h b/reactos/base/applications/taskmgr/graphctl.h index e924716e3e9..3a5b8388150 100644 --- a/reactos/base/applications/taskmgr/graphctl.h +++ b/reactos/base/applications/taskmgr/graphctl.h @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * GraphCtrl.h + * graphctl.h * * Copyright (C) 2002 Robert Dickenson * diff --git a/reactos/base/applications/taskmgr/optnmenu.c b/reactos/base/applications/taskmgr/optnmenu.c index 931e00c25fc..4ba1fa60336 100644 --- a/reactos/base/applications/taskmgr/optnmenu.c +++ b/reactos/base/applications/taskmgr/optnmenu.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * optnmenu.cpp + * optnmenu.c * * Copyright (C) 1999 - 2001 Brian Palmer * @@ -110,7 +110,7 @@ void TaskManager_OnOptionsShow16BitTasks(void) /* * FIXME: Currently this is useless because the - * current implemetation doesn't list the 16-bit + * current implementation doesn't list the 16-bit * processes. I believe that would require querying * each ntvdm.exe process for it's children. */ diff --git a/reactos/base/applications/taskmgr/perfdata.c b/reactos/base/applications/taskmgr/perfdata.c index a1095e5acd6..a82eb78ef1e 100644 --- a/reactos/base/applications/taskmgr/perfdata.c +++ b/reactos/base/applications/taskmgr/perfdata.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * perfdata.cpp + * perfdata.c * * Copyright (C) 1999 - 2001 Brian Palmer * diff --git a/reactos/base/applications/taskmgr/perfpage.c b/reactos/base/applications/taskmgr/perfpage.c index 8ba87eb067d..872a01406f9 100644 --- a/reactos/base/applications/taskmgr/perfpage.c +++ b/reactos/base/applications/taskmgr/perfpage.c @@ -51,11 +51,14 @@ HWND hPerformancePageTotalsHandleCountEdit; /* Total Handles Edit Con HWND hPerformancePageTotalsProcessCountEdit; /* Total Processes Edit Control */ HWND hPerformancePageTotalsThreadCountEdit; /* Total Threads Edit Control */ +#ifdef RUN_PERF_PAGE +static HANDLE hPerformanceThread = NULL; +static DWORD dwPerformanceThread; +#endif static int nPerformancePageWidth; static int nPerformancePageHeight; static int lastX, lastY; -static HANDLE hPerformancePageEvent = NULL; /* When this event becomes signaled then we refresh the performance page */ DWORD WINAPI PerformancePageRefreshThread(void *lpParameter); void AdjustFrameSize(HWND hCntrl, HWND hDlg, int nXDifference, int nYDifference, int pos) @@ -94,12 +97,12 @@ void AdjustFrameSize(HWND hCntrl, HWND hDlg, int nXDifference, int nYDifference, InvalidateRect(hCntrl, NULL, TRUE); } -void AdjustControlPostion(HWND hCntrl, HWND hDlg, int nXDifference, int nYDifference) +static void AdjustControlPostion(HWND hCntrl, HWND hDlg, int nXDifference, int nYDifference) { AdjustFrameSize(hCntrl, hDlg, nXDifference, nYDifference, 0); } -void AdjustCntrlPos(int ctrl_id, HWND hDlg, int nXDifference, int nYDifference) +static void AdjustCntrlPos(int ctrl_id, HWND hDlg, int nXDifference, int nYDifference) { AdjustFrameSize(GetDlgItem(hDlg, ctrl_id), hDlg, nXDifference, nYDifference, 0); } @@ -110,9 +113,6 @@ PerformancePageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) RECT rc; int nXDifference; int nYDifference; -#ifdef RUN_PERF_PAGE - HANDLE hRefreshThread = NULL; -#endif /* HDC hdc; */ /* PAINTSTRUCT ps; */ @@ -121,7 +121,7 @@ PerformancePageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GraphCtrl_Dispose(&PerformancePageCpuUsageHistoryGraph); GraphCtrl_Dispose(&PerformancePageMemUsageHistoryGraph); #ifdef RUN_PERF_PAGE - CloseHandle(hRefreshThread); + EndLocalThread(&hPerformanceThread, dwPerformanceThread); #endif break; @@ -192,7 +192,7 @@ PerformancePageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GraphCtrl_SetPlotColor(&PerformancePageMemUsageHistoryGraph, 0, RGB(255, 255, 0)) ; /* Start our refresh thread */ #ifdef RUN_PERF_PAGE - hRefreshThread = CreateThread(NULL, 0, PerformancePageRefreshThread, NULL, 0, NULL); + hPerformanceThread = CreateThread(NULL, 0, PerformancePageRefreshThread, NULL, 0, &dwPerformanceThread); #endif /* @@ -303,9 +303,11 @@ PerformancePageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) void RefreshPerformancePage(void) { +#ifdef RUN_PERF_PAGE /* Signal the event so that our refresh thread */ /* will wake up and refresh the performance page */ - SetEvent(hPerformancePageEvent); + PostThreadMessage(dwPerformanceThread, WM_TIMER, 0, 0); +#endif } DWORD WINAPI PerformancePageRefreshThread(void *lpParameter) @@ -332,35 +334,21 @@ DWORD WINAPI PerformancePageRefreshThread(void *lpParameter) WCHAR Text[260]; WCHAR szMemUsage[256]; - /* Create the event */ - hPerformancePageEvent = CreateEventW(NULL, TRUE, TRUE, NULL); - - /* If we couldn't create the event then exit the thread */ - if (!hPerformancePageEvent) - return 0; + MSG msg; LoadStringW(hInst, IDS_STATUS_MEMUSAGE, szMemUsage, 256); while (1) { - DWORD dwWaitVal; - int nBarsUsed1; int nBarsUsed2; - /* Wait on the event */ - dwWaitVal = WaitForSingleObject(hPerformancePageEvent, INFINITE); - - /* If the wait failed then the event object must have been */ - /* closed and the task manager is exiting so exit this thread */ - if (dwWaitVal == WAIT_FAILED) + /* Wait for an the event or application close */ + if (GetMessage(&msg, NULL, 0, 0) <= 0) return 0; - if (dwWaitVal == WAIT_OBJECT_0) + if (msg.message == WM_TIMER) { - /* Reset our event */ - ResetEvent(hPerformancePageEvent); - /* * Update the commit charge info */ @@ -449,8 +437,6 @@ DWORD WINAPI PerformancePageRefreshThread(void *lpParameter) PhysicalMemoryAvailable = PerfDataGetPhysicalMemoryAvailableK(); nBarsUsed2 = PhysicalMemoryTotal ? ((PhysicalMemoryAvailable * 100) / PhysicalMemoryTotal) : 0; - - GraphCtrl_AppendPoint(&PerformancePageCpuUsageHistoryGraph, CpuUsage, CpuKernelUsage, 0.0, 0.0); GraphCtrl_AppendPoint(&PerformancePageMemUsageHistoryGraph, nBarsUsed1, nBarsUsed2, 0.0, 0.0); /* PerformancePageMemUsageHistoryGraph.SetRange(0.0, 100.0, 10) ; */ @@ -458,7 +444,7 @@ DWORD WINAPI PerformancePageRefreshThread(void *lpParameter) InvalidateRect(hPerformancePageCpuUsageHistoryGraph, NULL, FALSE); } } - return 0; + return 0; } void PerformancePage_OnViewShowKernelTimes(void) diff --git a/reactos/base/applications/taskmgr/procpage.c b/reactos/base/applications/taskmgr/procpage.c index 42bf5949ea7..acaa159bd04 100644 --- a/reactos/base/applications/taskmgr/procpage.c +++ b/reactos/base/applications/taskmgr/procpage.c @@ -40,7 +40,10 @@ HWND hProcessPageShowAllProcessesButton;/* Process Show All Processes checkbox * static int nProcessPageWidth; static int nProcessPageHeight; -static HANDLE hProcessPageEvent = NULL; /* When this event becomes signaled then we refresh the process list */ +#ifdef RUN_PROC_PAGE +static HANDLE hProcessThread = NULL; +static DWORD dwProcessThread; +#endif int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); void AddProcess(ULONG Index); @@ -104,7 +107,6 @@ ProcessPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) int nXDifference; int nYDifference; int cx, cy; - HANDLE hRefreshThread = NULL; switch (message) { case WM_INITDIALOG: @@ -139,19 +141,19 @@ ProcessPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) */ OldProcessListWndProc = (WNDPROC)(LONG_PTR) SetWindowLongPtrW(hProcessPageListCtrl, GWL_WNDPROC, (LONG_PTR)ProcessListWndProc); +#ifdef RUN_PROC_PAGE /* Start our refresh thread */ - hRefreshThread = CreateThread(NULL, 0, ProcessPageRefreshThread, NULL, 0, NULL); - + hProcessThread = CreateThread(NULL, 0, ProcessPageRefreshThread, NULL, 0, &dwProcessThread); +#endif return TRUE; case WM_DESTROY: /* Close the event handle, this will make the */ /* refresh thread exit when the wait fails */ - CloseHandle(hProcessPageEvent); - CloseHandle(hRefreshThread); - +#ifdef RUN_PROC_PAGE + EndLocalThread(&hProcessThread, dwProcessThread); +#endif SaveColumnSettings(); - break; case WM_COMMAND: @@ -194,11 +196,9 @@ ProcessPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) cy = rc.top + nYDifference; SetWindowPos(hProcessPageShowAllProcessesButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); InvalidateRect(hProcessPageShowAllProcessesButton, NULL, TRUE); - break; case WM_NOTIFY: - ProcessPageOnNotify(wParam, lParam); break; } @@ -372,9 +372,11 @@ void ProcessPageShowContextMenu(DWORD dwProcessId) void RefreshProcessPage(void) { +#ifdef RUN_PROC_PAGE /* Signal the event so that our refresh thread */ /* will wake up and refresh the process page */ - SetEvent(hProcessPageEvent); + PostThreadMessage(dwProcessThread, WM_TIMER, 0, 0); +#endif } DWORD WINAPI ProcessPageRefreshThread(void *lpParameter) @@ -382,34 +384,19 @@ DWORD WINAPI ProcessPageRefreshThread(void *lpParameter) ULONG OldProcessorUsage = 0; ULONG OldProcessCount = 0; WCHAR szCpuUsage[256], szProcesses[256]; - - /* Create the event */ - hProcessPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL); - - /* If we couldn't create the event then exit the thread */ - if (!hProcessPageEvent) - return 0; + MSG msg; LoadStringW(hInst, IDS_STATUS_CPUUSAGE, szCpuUsage, 256); LoadStringW(hInst, IDS_STATUS_PROCESSES, szProcesses, 256); while (1) { - DWORD dwWaitVal; - - /* Wait on the event */ - dwWaitVal = WaitForSingleObject(hProcessPageEvent, INFINITE); - - /* If the wait failed then the event object must have been */ - /* closed and the task manager is exiting so exit this thread */ - if (dwWaitVal == WAIT_FAILED) + /* Wait for an the event or application close */ + if (GetMessage(&msg, NULL, 0, 0) <= 0) return 0; - if (dwWaitVal == WAIT_OBJECT_0) { + if (msg.message == WM_TIMER) { WCHAR text[260]; - /* Reset our event */ - ResetEvent(hProcessPageEvent); - UpdateProcesses(); if (IsWindowVisible(hProcessPage)) diff --git a/reactos/base/applications/taskmgr/taskmgr.c b/reactos/base/applications/taskmgr/taskmgr.c index c409f808b1f..c6d11c0e54d 100644 --- a/reactos/base/applications/taskmgr/taskmgr.c +++ b/reactos/base/applications/taskmgr/taskmgr.c @@ -1,7 +1,7 @@ /* * ReactOS Task Manager * - * TaskMgr.c : Defines the entry point for the application. + * taskmgr.c : Defines the entry point for the application. * * Copyright (C) 1999 - 2001 Brian Palmer * 2005 Klemens Friedl @@ -856,11 +856,6 @@ void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed) SetUpdateSpeed(hMainWnd); } -void TaskManager_OnViewRefresh(void) -{ - PostMessageW(hMainWnd, WM_TIMER, 0, 0); -} - void TaskManager_OnTabWndSelChange(void) { int i; @@ -1012,3 +1007,27 @@ LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize) } return lpszBuf; } + +DWORD EndLocalThread(HANDLE *hThread, DWORD dwThread) +{ + DWORD dwExitCodeThread = 0; + + if (*hThread != NULL) { + PostThreadMessage(dwThread,WM_QUIT,0,0); + for (;;) { + MSG msg; + + if (WAIT_OBJECT_0 == WaitForSingleObject(*hThread, 500)) + break; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + GetExitCodeThread(*hThread, &dwExitCodeThread); + CloseHandle(*hThread); + *hThread = NULL; + } + return dwExitCodeThread; +} + diff --git a/reactos/base/applications/taskmgr/taskmgr.h b/reactos/base/applications/taskmgr/taskmgr.h index 16eaad8224a..e0a8de842d9 100644 --- a/reactos/base/applications/taskmgr/taskmgr.h +++ b/reactos/base/applications/taskmgr/taskmgr.h @@ -116,9 +116,9 @@ void TaskManager_OnEnterMenuLoop(HWND hWnd); void TaskManager_OnExitMenuLoop(HWND hWnd); void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu); void TaskManager_OnViewUpdateSpeed(DWORD); -void TaskManager_OnViewRefresh(void); void TaskManager_OnTabWndSelChange(void); LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ); +DWORD EndLocalThread(HANDLE *hThread, DWORD dwThread); #ifdef __cplusplus }