From: Robert M. <rob...@us...> - 2007-07-29 12:19:50
|
On 29/07/07, Jan Dubois <ja...@ac...> wrote: > On Sat, 28 Jul 2007, Robert May wrote: > > On 28/07/07, Jan Dubois <ja...@ac...> wrote: > > > CreateProcess() will return and not wait for command.com/cmd.exe to > > > initialize. Upon return win32_spawnvp() will call win32_msgwait(), > > > which should continue to pump the message loop until the external > > > process ends. > > > > That's what's supposed to happen, but in AS build 819 on win98 (that's > > all I have access to this weekend), I have to change the flags to > > MsgWaitForMultipleObjects from QS_ALLEVENTS to > > QS_ALLEVENTS|QS_SENDMESSAGE to get it to pump the sent WM_DDE_INITIATE > > message. > > Alright, I looked at the code again, and the real problem is: > win32_msgwait() doesn't actually dispatch any messages; it only > processes (via win32_async_check()) WM_TIMER and WM_USER messages sent > to hwnd NULL. PeekMessage() will dispatch sent messages, (apparently) regardless of the filtering applied. Certainly on Win98 all I have to change to fix this particular DDE problem is to add QS_SENDMESSAGE to the MsgWaitForMultipleObjects() to get it to return if there is a sent message in the queue - even if I've called alarm(0); to make w32_hwnd_message not equal to INVALID_HANDLE_VALUE, so that we do the 'thread message only' PeekMessage, the DDE problem is gone. > The whole reason for *not* running a message pump is to allow an > embedding application to use PostThreadMessage() too. If we ran a > message pump, we wouldn't know what to do with messages sent to hwnd > NULL that we are not expecting. Right. But there are good reasons not to run a full message pump. For example, from a Win32::GUI point of view I really don't want win32_async_check to be dispatching keyboard messages for me - first, I may want to be using a message pump with more complexity that simply doing a TranslateMessage/DispatchMessage - I may want to dela with dialog messages (IsDialogMessage()) and accelerators (IsAcceleleratorMessage()). I think it would be very confusing if, for example, sleep() started behaving like this. > But given the problem you discovered with DDE initiation while waiting > for system() to return, I think win32_async_check() needs to run a > message pump. I think it's already doing enough. The DDE problem is that MsgWaitForMultipleObjects isn't returning for the *sent* WM_DDE_INITIATE message. > Given that the whole PostThreadMessage() mechanism is too > brittle for GUI threads anyways (you cannot avoid losing messages), I > doubt anyone is using it while also embedding Perl. I wouldn't bet on it. What we should do is put a call to CallMsgFilter() in any message pump loop we have that might pull thread messages off the queue, to give someone else a chance to see then, if they need to (See http://blogs.msdn.com/oldnewthing/archive/2005/04/28/412574.aspx for more info) > While looking at this issue I noticed that even though we are using a > message-only window on Windows 2000 and later, we are not actually > expecting anybody else to dispatch the messages to a wndproc; we always > try to snatch them out of the queue via PeekMessage(). So we still > inherit the brittleness of the PostThreadMessage() mechanism. This is a problem that I have on my list of things to look at. In particular, even if we're using a message-only window, someone else's message pump (e.g the one run by Win32::MsgBox, may pull our messages from the queue and translate/dispatch them. As we are not handling the messages in the window's wndproc, they never get processed. > I'll see if I can come up with a patch for both issues some time later > next week. Currently I'm leaning towards just adding QS_SENDMESSAGE to the MsgWaitForMultipleObjects() call - we'll need to do this anyway to solve the DDE problem, and I think it's a small enough change to propose for 5.10. I think anything else we do will be a much bigger change, and will probably have to wait for after that. I'll spent some more time thinking about this during the week. Should we move this discussion to P5P? > PS: Please let me know if you happen to know a mechanism to create a > message-only window on 98/NT (a window that is not top-level and > will not receive broadcast messages). If this were possible, then we > could get rid of PostThreadMessage() completely. I'm not aware of a way, but I'll do some research. I'm pretty sure that we don't wan ta real top-level window .... Regards, Rob. |