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