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.

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().

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

Reply via email to