- Pause event handler, go enter another one, then come back - 6 Updates
- struct or class? - 6 Updates
- An argument *against* (the liberal use of) references - 1 Update
- Microsoft Visual Studio 2022 (C++) buggy as hell - 4 Updates
- Vector Fractal Bloom... - 2 Updates
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Nov 30 05:46AM -0800 I was looking through old code of mine that I wrote 10 - 15 years ago, and I saw this: void Dialog_Main::OnButtonClick_SeeDetails( wxCommandEvent& event ) { (new Dialog_Details(this,p))->ShowModal(); /* This function call doesn't return until the dialog disappears, however wxWidgets has some sort of sorcery going on in the background that lets it jump out and process other events, then come back to finish this one. */ /* Do more processing after dialog disappears */ } There is only one GUI thread in wxWidgets. Any event is always processed inside an event handler by the GUI thread. But some how, some way, wxWidget is able to pause one event handler half way through, then go execute another event, then come back to the original event handler and continue where it left off. I posted on the wxWidgets forum ages ago about this: https://forums.wxwidgets.org/viewtopic.php?f=27&t=48833 And it seems that wxWidgets gets this behaviour from the underlying native API. So in the case of Microsoft Windows, it would be the Win32 API. Years and years and years ago I remember writing Win32 code with a message loop with "GetMessage" to do the processing for a dialog box, but I never recall the possibility of event handlers being 'interwoven' so to speak. Has anyone seen this kind of thing before? The only way I can fathom this working, i.e. for a thread to interrupt itself and execute some other code, then return to where it was previously, is if a signal is raised -- but there are major restrictions on what can happen inside a signal handler. Does anyone know how this works? |
Paavo Helde <eesnimi@osa.pri.ee>: Nov 30 04:41PM +0200 30.11.2022 15:46 Frederick Virchanza Gotham kirjutas: > Years and years and years ago I remember writing Win32 code with a message loop with "GetMessage" to do the processing for a dialog box, but I never recall the possibility of event handlers being 'interwoven' so to speak. > Has anyone seen this kind of thing before? The only way I can fathom this working, i.e. for a thread to interrupt itself and execute some other code, then return to where it was previously, is if a signal is raised -- but there are major restrictions on what can happen inside a signal handler. > Does anyone know how this works? Something like what you describe could be done by coroutines. But here, with modal dialogs the things are simpler, it's just a recursive call to some kind of PumpMessage loop. In Windows all events are placed in the window event queue, there are functions for processing them, typically called something like PumpMessage, and when processing some event, the handler code can contain a new message loop which will process all the messages by itself for a while. Here is a call stack from an event handler inside a modal dialog, with many frames omitted for brevity. This is from MFC, not wxWidgets, but they should be similar enough here. Note how e.g. CWinThread::PumpMessage() appears twice in the call stack, meaning that it is called recursively. The first event processing loop is apparently in CWinThread::Run() in the bottom of the stack, and the second one is in CWnd::RunModalLoop(). [....] mfc140ud.dll!AfxPreTranslateMessage(tagMSG * pMsg) Line 252 C++ mfc140ud.dll!AfxInternalPumpMessage() Line 178 C++ mfc140ud.dll!CWinThread::PumpMessage() Line 900 C++ mfc140ud.dll!AfxPumpMessage() Line 190 C++ > mfc140ud.dll!CWnd::RunModalLoop(unsigned long dwFlags) Line 4661 C++ mfc140ud.dll!CWnd::CreateRunDlgIndirect(const DLGTEMPLATE * lpDialogTemplate, CWnd * pParentWnd, HINSTANCE__ * hInst) Line 485 C++ mfc140ud.dll!CDialog::DoModal() Line 652 C++ [..........] mfc140ud.dll!CWnd::IsDialogMessageW(tagMSG * lpMsg) Line 194 C++ mfc140ud.dll!CWnd::PreTranslateInput(tagMSG * lpMsg) Line 4607 C++ mfc140ud.dll!CControlBar::PreTranslateMessage(tagMSG * pMsg) Line 440 C++ mfc140ud.dll!CControlBar::PreTranslateMessage(tagMSG * pMsg) Line 431 C++ mfc140ud.dll!CWnd::WalkPreTranslateTree(HWND__ * hWndStop, tagMSG * pMsg) Line 3379 C++ mfc140ud.dll!AfxInternalPreTranslateMessage(tagMSG * pMsg) Line 233 C++ mfc140ud.dll!CWinThread::PreTranslateMessage(tagMSG * pMsg) Line 778 C++ mfc140ud.dll!AfxPreTranslateMessage(tagMSG * pMsg) Line 252 C++ mfc140ud.dll!AfxInternalPumpMessage() Line 178 C++ mfc140ud.dll!CWinThread::PumpMessage() Line 900 C++ mfc140ud.dll!CWinThread::Run() Line 629 C++ mfc140ud.dll!CWinApp::Run() Line 787 C++ EvoShellD.exe!CShellApp::Run() Line 1051 C++ mfc140ud.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 47 C++ EvoShellD.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 26 C++ EvoShellD.exe!invoke_main() Line 123 C++ EvoShellD.exe!__scrt_common_main_seh() Line 288 C++ EvoShellD.exe!__scrt_common_main() Line 331 C++ EvoShellD.exe!wWinMainCRTStartup(void * __formal) Line 17 C++ kernel32.dll!00007ffc7f5e74b4() Unknown ntdll.dll!00007ffc815026a1() Unknown |
Ralf Fassel <ralfixx@gmx.de>: Nov 30 05:48PM +0100 * Frederick Virchanza Gotham <cauldwell.thomas@gmail.com> | I was looking through old code of mine that I wrote 10 - 15 years ago, and I saw this: | void Dialog_Main::OnButtonClick_SeeDetails( wxCommandEvent& event ) | { | (new Dialog_Details(this,p))->ShowModal(); | | /* This function call doesn't return until the | dialog disappears, however wxWidgets has some | sort of sorcery going on in the background that lets it | jump out and process other events, then come | back to finish this one. */ | | /* Do more processing after dialog disappears */ | } --<snip-snip>-- | But some how, some way, wxWidget is able to pause one event handler | half way through, then go execute another event, then come back to the | original event handler and continue where it left off. --<snip-snip>-- | Does anyone know how this works? I don't know for sure for wxWidgets, but how should it process the dialog (button presses etc) if not by entering another event loop? If you look at the source of wxDialog::ShowModal() (which seems to be the workhorse for all the modals): int wxDialog::ShowModal() { ... gtk_grab_add( m_widget ); wxEventLoop().Run(); gtk_grab_remove( m_widget ); ... } which looks just like re-entering the event-loop. As an aside, e.g. the TCL/Tk scripting language has explicit commands in scripting and C-level to enter recursive event loops ('update', 'vwait', Tcl_DoOneEvent()), so that does not seem very uncommon. R' |
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Nov 30 01:16PM -0800 On Wednesday, November 30, 2022 at 4:49:01 PM UTC, Ralf Fassel wrote: > ... > } > which looks just like re-entering the event-loop. Ok I see how that would work. I think I'd prevent re-entry of an event handler as follows: #include <atomic> void Dialog_Main::OnClick_Button(wxCommandEvent &e) { static std::atomic_flag lock = ATOMIC_FLAG_INIT; if ( lock.test_and_set() ) { e.Skip(); return; } try { // The main body of the event handler goes here } catch(...) { lock.clear(); throw; } } |
scott@slp53.sl.home (Scott Lurndal): Nov 30 09:53PM > throw; > } >} Generally GUI event handlers are all called in the context of a single thread. Locking the handler should not be required, however, protecting[*] any data which may be shared by the event handler with other threads is mandatory. [*] either explicitly with a synchronization primitive or implicitly by using the appropriate atomic operations, if applicable. |
scott@slp53.sl.home (Scott Lurndal): Nov 30 09:55PM >by the event handler with other threads is mandatory. >[*] either explicitly with a synchronization primitive or implicitly > by using the appropriate atomic operations, if applicable. As for pausing the event handler, the canonical way is to enter the event handler, queue the event to another thread, then return from the event handler. |
"Öö Tiib" <ootiib@hot.ee>: Nov 29 04:04PM -0800 > Isn't it amazing how people managed before OO came along? In C they used pointers to opaque types for encapsulation. Kind of like that FILE* of fopen(), fscanf(), fprintf() etc is used. |
Juha Nieminen <nospam@thanks.invalid>: Nov 30 07:42AM > Isn't it amazing how people managed before OO came along? This sounds to me like a case of "why do we even need measles vaccines anymore? There hasn't been a single case in decades." The thing is, when it works, you don't even notice. |
Muttley@dastardlyhq.com: Nov 30 06:44PM On Tue, 29 Nov 2022 18:38:02 +0000 >>>You need to learn what "encapsulation" means; only have a minimum of >> I know what it means thanks. >It is obvious that you don't. Don't confuse understanding with not giving a toss. >It is only a personal choice if you are a team of ONE. Do you even have a >day job? I would hate to work where you work if you do and they allow >such egregious behaviour. My day job doesn't involved C++ right now so thats irrelevant. |
Muttley@dastardlyhq.com: Nov 30 06:45PM On Tue, 29 Nov 2022 18:40:18 +0000 >> Thats why you provide a "use at your own risk" clause. >It isn't just your own risk, it is *everyone* who either uses or depends >on the code's risk. How does that work then? Either the code works or it doesn't. Have you heard of testing? Actually probably not, you probably think your code is perfect and don't bother. >> above. >> Isn't it amazing how people managed before OO came along? >"unofficial"? you must really crank out bags of shite on a daily basis. Just like you on here you mean? |
Muttley@dastardlyhq.com: Nov 30 06:46PM On Tue, 29 Nov 2022 16:04:40 -0800 (PST) >> Isn't it amazing how people managed before OO came along? >In C they used pointers to opaque types for encapsulation. Kind of like that >FILE* of fopen(), fscanf(), fprintf() etc is used. But you can access their internals if you want to. You might never want to but the option is there. |
scott@slp53.sl.home (Scott Lurndal): Nov 30 06:54PM >>FILE* of fopen(), fscanf(), fprintf() etc is used. >But you can access their internals if you want to. You might never want to >but the option is there. For intentionally opaque objects like struct FILE, that would be an egregiously bad thing to do. And for some impl., it is impossible because the internals are one (implementation defined) object behind struct FILE which simply contains a void* pointer to the real object |
Paavo Helde <eesnimi@osa.pri.ee>: Nov 30 01:59PM +0200 23.11.2022 15:46 Juha Nieminen kirjutas: > value or by reference. (OTOH this may be much more efficient if > the function takes a significant amount of time because you don't > need to keep the mutex locked for the duration of the function.) Curiously enough, I just spent 3 days for tracking down a random race condition bug in a large application. It appeared that for fixing it I had to add a single ampersand character, i.e. instead of making a copy of the object I had to just take a reference to it. Note this is the exact opposite of the general suggestion you advocated earlier ;-) Actually once located, the bug was simple. The object which was copied was a single-threaded refcounted smartpointer, and by copying it the refcounter got incremented (and later decremented). Alas, this was accidentally done from parallel threads at the same time, without any synchronization, so eventually the refcounter got messed up. After fixing it by taking a reference to the smartpointer instead of copying it, the refcounter now remains constant all the time throughout the parallel regime (and all other access is read-only as well), so everything now works fine. In principle one could make copies of the pointed objects before the parallel regime, or in this particular case it would have been enough to use thread-safe smartpointers, but both these approaches would affect the performance, and we are always struggling with the performance. |
Mr Flibble <flibble@reddwarf.jmc.corp>: Nov 29 11:56PM On Tue, 29 Nov 2022 16:12:14 -0600, Lynn McGuire wrote: > years late. I got my first diskettes for Windows 93 in 1992. > I guess I got MSVC 1.0 in 1993. I remember Win32s very well. > Lynn There was no such thing as Windows 93. /Flibble |
Lynn McGuire <lynnmcguire5@gmail.com>: Nov 29 06:24PM -0600 On 11/29/2022 5:56 PM, Mr Flibble wrote: >> Lynn > There was no such thing as Windows 93. > /Flibble I could take a picture of the diskettes but I threw them away years ago. I got diskettes from MS at least once a month. They were desperately trying to create more window handles without killing all of the Win16 software out there like mine. Unfortunately, they gave up after a year or so and shipped Windows 95. Lynn |
"Öö Tiib" <ootiib@hot.ee>: Nov 30 12:41AM -0800 On Wednesday, 30 November 2022 at 02:24:59 UTC+2, Lynn McGuire wrote: > trying to create more window handles without killing all of the Win16 > software out there like mine. Unfortunately, they gave up after a year > or so and shipped Windows 95. I remember 95 ... it was like 2 boxes of floppies. We installed it on some computers and experience was rather bad compared to Windows 3.11 and Windows NT 3.5 that we had used before. During few months we decided that perhaps it is time to switch mostly to NT and keep 3.11 and 95 only for testing/debugging of compatibility. In few years customers also all migrated to NT 3.5 and NT 4 and so the 95 line did die off. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Nov 30 01:07AM -0800 On 11/26/2022 3:29 PM, Mr Flibble wrote: >> I found some oddities in 17.4.1 wrt the IDE, but nothing major. > Well I would classify a non-working debugger and ICEs are pretty fucking > major. Nothing bad in the debugger, yet. So far so good for my current use cases. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Nov 29 09:22PM -0800 On 5/12/2022 12:16 PM, Chris M. Thomasson wrote: > Using my experimental vector field to generate a fractal formation. Here > is generation two: > https://fractalforums.org/gallery/1612-120522191048.png Nice! https://i.ibb.co/VqcPMvg/image.png I am up against some really excellent works! Silver works great for me. C++ is great! |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Nov 29 09:34PM -0800 On 11/29/2022 9:22 PM, Chris M. Thomasson wrote: > https://i.ibb.co/VqcPMvg/image.png > I am up against some really excellent works! Silver works great for me. > C++ is great! Fwiw, here is a little animation I made of aSprial (the Silver) ;^), a while back: https://youtu.be/ljeN7dYNHhQ |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment