[fpc-devel] Inconsistent use of Timeout in SimpleIPC

Michael Van Canneyt michael at freepascal.org
Sat Dec 5 12:54:54 CET 2015



On Fri, 4 Dec 2015, Denis Kozlov wrote:

> There is another problem with SimpleIPC on Windows.
>
> This same problem was experienced in @Juha's post "SimpleIPC and
> TWinMsgServerComm.PeekMessage":
> http://lists.freepascal.org/pipermail/fpc-devel/2013-October/032871.html
>
> TWinMsgServerComm.PeekMessage never waits for a Timeout because of this
> line:
>> MsgWaitForMultipleObjects(1,FHWND,False,TimeOut,QS_SENDMESSAGE);
>
> It always fails and returns immediately WAIT_FAILED with GetLastError
> saying "Invalid handle". As per documentation at MSDN,
> MsgWaitForMultipleObjects does not work with window handles. Funny thing is
> that I am pretty sure that this line used to work in the past, on much
> older OS, perhaps XP before SP3 or earlier. It used to be able to wait, but
> definitely not any more (tested on 7 SP1 and XP SP3).
>
> I suspect that the reason why it might have worked in the past is because
> MsgWaitForMultipleObjects behind the scene (according to MS engineers) also
> waits for a signal on the current thread (in addition to signals on
> whatever handles you provide). I also suspect that on older OS versions
> MsgWaitForMultipleObjects did not fail and return immediately if one of
> those handles was invalid, meaning that it will continue waiting for a
> signal to the current thread, which would then get signalled when a thread
> message arrived and it actually would perform as intended.
>
> On newer OS, it seems that MsgWaitForMultipleObjects always fails and
> returns immediately if one of the supplied handles was invalid for its
> purposes, e.g. window handle is supplied. It won't bother waiting for a
> signal on thread behind the scene.
>
> It can be resolved in one of 2 ways:
> A) MsgWaitForMultipleObjects(0, nil, False, TimeOut, QS_SENDMESSAGE); //
> wait for thread messages, window must be owned by the same thread.
> B) SetTimer(HWND, Timeout); GetMessage(HWND); KillTimer; // use blocking
> GetMessage, unblock it via WM_TIMER.

I think B is the way to go; So the code doesn't assume anything about threads.

Michael.



More information about the fpc-devel mailing list