There's one additional thing we might consider implementing here. The waiting activities queue is implemented using a linked list where the link fields are directly contained within the activity object. This causes problems if there is a reentrant situation that can cause the same activity to be added to the queue more than once. When that happens, it's guaranteed bad day. The changes you have proposed can step around the problem, but won't really close all of the holes where this situation might occur. It might not be a bad idea to replace that linked list with a std collection object for managing the activity queue. With that situation, it doesn't really matter if the recursion occurs. The internal control blocks will allow an activity to be queued up multiple times without causing a problem. This *should* be a simple change....ignoring for the moment all of the problems I had the last time I tried to use a std collection class :-)
Rick On Thu, Feb 4, 2010 at 4:47 AM, Rick McGuire <object.r...@gmail.com> wrote: > 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