Charles Davis cdavis@mymail.mines.edu wrote on 2010/05/03 01:18:25:
On 5/2/10 3:02 PM, Joakim Tjernlund wrote:
Noticed that RtlRegisterWait() will approve a zero timeout value(Milliseconds == 0)
This makes ies4linux spin the CPU 100% when visiting a https page. The below crude patch fixes it:
--- dlls/ntdll/threadpool.c.org 2010-05-02 22:37:08.000000000 +0200 +++ dlls/ntdll/threadpool.c 2010-05-02 22:46:45.000000000 +0200 @@ -427,6 +427,9 @@
TRACE( "(%p, %p, %p, %p, %d, 0x%x)\n", NewWaitObject, Object, Callback,
Context, Milliseconds, Flags );
- if (!Milliseconds)
- return RPC_NT_INVALID_TIMEOUT;
- wait_work_item = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*wait_work_item) ); if (!wait_work_item) return STATUS_NO_MEMORY;
On a related note, whitout this patch wineserver also goes into an endless loop, doing brk() calls over and over until memory is exausted. Seems like a bug that too.
This looks like something you should post to wine-devel.
Right, posting there but with a new patch. I think the orginal fix was wrong. Here is a new one:
From 2f5e169e286265bb82b17f76023c463bc2a96703 Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund Joakim.Tjernlund@transmode.se Date: Mon, 3 May 2010 09:03:09 +0200 Subject: [PATCH] RegisterWaitForSingleObjectX(), fix tmo == 0
Timeout == 0 is special, from the manual: The time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If dwMilliseconds is zero, the function tests the object's state and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
1) Only call Callback iff signaled 2) Implies WT_EXECUTEONLYONCE. 3) Callback should be called before returning.
This is a crude fix not impl. 3) but is enough to get ies4linux around the 100% CPU problem. Not sure tmo == 0 implies returning a NULL ptr for phNewWaitObject too. --- dlls/ntdll/threadpool.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c index 44afb01..159baee 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c @@ -373,11 +373,17 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg) wait_work_item->Context ); TimerOrWaitFired = TRUE; } - wait_work_item->CallbackInProgress = TRUE; - wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired ); - wait_work_item->CallbackInProgress = FALSE; + /* Milliseconds == 0 is special, only call Callback iff + signaled and treat as WT_EXECUTEONLYONCE */ + if (wait_work_item->Milliseconds || !TimerOrWaitFired) + { + wait_work_item->CallbackInProgress = TRUE; + wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired ); + wait_work_item->CallbackInProgress = FALSE; + }
- if (wait_work_item->Flags & WT_EXECUTEONLYONCE) + if (!wait_work_item->Milliseconds || + wait_work_item->Flags & WT_EXECUTEONLYONCE) break; } else -- 1.6.4.4