On Wed, Feb 3, 2010 at 11:32 PM, Mark Miesfeld <miesf...@gmail.com> wrote:
> Rick
>
> (For some reason your mail didn't show up until hours after you sent it.)
>
> I have a solution that, so far, in all my testing seems to work.  I'm
> not sure how to fully implement it, or if it is feasible.  It has two
> parts:
>
> 1.)  I think this is feasible and indeed I think should probably be
> done in any case.  On Windows, the implementation of
> SysActivity::relinquish() is this:
>
> void SysActivity::relinquish()
> {
>    MSG msg;
>
>    /*  If there is a msg in the message queue, dispatch it to the appropriate
>     *  window proc.
>     */
>
>    if (PeekMessage (&msg,   // message structure
>                     NULL,                  // handle of window
> receiving the message
>                     0,                     // lowest message to examine
>                     0,
>                     PM_REMOVE))            // highest message to examine
>    {
>        TranslateMessage(&msg);// Translates virtual key codes
>        DispatchMessage(&msg); // Dispatches message to window
>    }
> }
>
> This looks to me like a hold over from Windows 3.1 non-preemptive
> multi-tasking where there was only PeekMessage, GetMessage, and Yield
> that would give the processor a chance to run another task.  From what
> I've seen, a lot of the Windows 95 programming texts encouraged the
> programmer to still write "well behaved" applications that yielded the
> thread.  So, I think this implementation is left over from that era.
>
> I think PeekMessag() could be replaced with Sleep(1) which would allow
> any other waiting threads to run.

I'm certainly ok with doing that.


>
> 2.) The other problem is in waitHandle(), which in my looking at this
> over the past week is actually the one that usually causes the
> problem.  There we have PeekMessage() running in a loop:
>
>    do
>    {
>        while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
>        {
>            TranslateMessage(&msg);
>            DispatchMessage(&msg);
>
>            // Check to see if signaled.
>            if ( WaitForSingleObject(s, 0) == WAIT_OBJECT_0 )
>            {
>                return;
>            }
>        }
>    } while ( MsgWaitForMultipleObjects(1, &s, FALSE, INFINITE,
> QS_ALLINPUT) == WAIT_OBJECT_0 + 1 );
>
> The point of this was to process messages in threads that, possibly,
> had hidden windows.  It wasn't meant for threads that had an active
> message pump, as the WindowUsrLoopThread and WindowLoopThread do.
>
> What I was thinking was:  for the C++ API, add an API for AttachThread
> that took a parameter which marked the activity for that thread to
> avoid PeekMessage.  Them from ActivityManager::addWaitingActivity this
> flag would get passed down to waitKernel() and ultimately
> waitHandle().

I'm not really in favor of exposing this bit of Windows-specific
problem in the portable APIs.  Maybe the solution is to make the
RexxSetMessageLoop() API functional again, but have it work on a
per-thread basis rather than globally the way it used to.


>
> In waitHandle() sort of pseudo code would be:
>
> inline void waitHandle(HANDLE s, bool noPeek)
> {
>    if ( noPeek )
>    {
>        WaitForSingleObject(s, INFINITE);
>        return;
>    }
>    else
>    {
>        <do what waitHandle() does now>
>    }
> }
>
> (Actually the same flag could be passed to SysActivity::relinquish()
> to do a Sleep() instead of a PeekMessage(), I just don't think the
> PeekMessage() is needed in that method to begin with.)
>
> What I did as a quick hack to test this was change SysActivity::relinquish to
>
> void SysActivity::relinquish()
> {
>    Sleep(1);
>    return;
> }
>
> and waitHandle() to this:
>
> inline void waitHandle(HANDLE s)
> {
>    WaitForSingleObject(s, INFINITE);
>    return;
>
>  ... other code remains, just will never execute
> }
>
> and with that I could never reproduce the problem.
>
> I think you are right in that with the current code something
> definitely gets corrupted.
>
> Your idea:
>
>> I wonder if we could somehow create a
>> thread local variable and keep a flag that would bypass the message
>> dispatch when this sort of reentrant situation occurs for a semaphore
>> request.
>
> Is essentially the same idea as mine, just marking the thread itself
> instead of the activity object.  I could probably implement something
> like that myself.  Marking the activity was a little beyond me.
>
> --
> Mark Miesfeld
>
> ------------------------------------------------------------------------------
> The Planet: dedicated and managed hosting, cloud storage, colocation
> Stay online with enterprise data centers and the best network in the business
> Choose flexible plans and management services without long-term contracts
> Personal 24x7 support from experience hosting pros just a phone call away.
> http://p.sf.net/sfu/theplanet-com
> _______________________________________________
> Oorexx-devel mailing list
> Oorexx-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/oorexx-devel
>

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to