Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Mysterious missing event code

Credits go to bamccaig for helping out!
This thread is locked; no one can reply to it. rss feed Print
Mysterious missing event code
Edgar Reynaldo
Member #8,592
May 2007
avatar

Hi,

I'm currently debugging my multi monitor code for Eagle and every time I shut down Eagle after creating a EagleGraphicsContext( a window ) it hangs in Allegro5WindowManager::Destroy here :
https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/backends/Allegro5/Allegro5WindowManager.cpp#L304-L314

The Allegro5WindowManager process is alive and waiting on an event (in this case, EAGLE_EVENT_WM_DESTROY :
https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/backends/Allegro5/Allegro5WindowManager.cpp#L37

which should have been sent by the above code, but that message never arrives. Can anyone help me debug this and figure out why my event is missing?

Edgar

bamccaig
Member #7,536
July 2006
avatar

This probably doesn't really help, but the first thing I thought of was if the Allegro event system is somehow tied to the window/display, and you destroy that, perhaps the event pipeline would get lost. Just a guess, and it's probably not true if the event queues don't require a display to function.

Edgar Reynaldo
Member #8,592
May 2007
avatar

ALLEGRO_EVENT_QUEUE and ALLEGRO_EVENT_SOURCE are both completely separate from an ALLEGRO_DISPLAY.

I don't know what's wrong. If I set a breakpoint in WM::Destroy I see the event get emitted! It is just never received by the A5WindowManagerProcess. I only unregister the event source once, on destruction later on in WM::Destroy here :
https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/backends/Allegro5/Allegro5WindowManager.cpp#L316-L321

I create and initialize and register them here :
https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/backends/Allegro5/Allegro5WindowManager.cpp#L264-L277

Those are the only places I create or destroy or register or unregister the window_event_source. This is everything grep returns that has anything to do with the window event source :

c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\src>grep -r -E -I -n "window_event_source" .*.*
.\backends/Allegro5/Allegro5WindowManager.cpp:42:      if (ev.any.source == &(a5man->window_event_source)) {
.\backends/Allegro5/Allegro5WindowManager.cpp:130:   ev.any.source = &window_event_source;
.\backends/Allegro5/Allegro5WindowManager.cpp:133:   al_emit_user_event(&window_event_source , &ev , 0);
.\backends/Allegro5/Allegro5WindowManager.cpp:150:   if (ev.any.source == &window_event_source) {
.\backends/Allegro5/Allegro5WindowManager.cpp:245:      window_event_source(),
.\backends/Allegro5/Allegro5WindowManager.cpp:264:   al_init_user_event_source(&window_event_source);
.\backends/Allegro5/Allegro5WindowManager.cpp:277:   al_register_event_source(window_queue , &window_event_source);
.\backends/Allegro5/Allegro5WindowManager.cpp:307:      ev.any.source = &window_event_source;
.\backends/Allegro5/Allegro5WindowManager.cpp:311:      al_emit_user_event(&window_event_source , &ev , 0);
.\backends/Allegro5/Allegro5WindowManager.cpp:317:      al_unregister_event_source(window_queue , &window_event_source);
.\backends/Allegro5/Allegro5WindowManager.cpp:318:      al_destroy_user_event_source(&window_event_source);

c:\ctwoplus\progcode\Eagle5GUI_GIT_BitBucket\src>

bamccaig
Member #7,536
July 2006
avatar

This is maybe a bit of a hack, but if you comment out the unregister/destroy event source business does the event arrive? I'm just curious if that would help to track down the cause.. I'm just guessing mind you. If I can find any ambition I could try to get it installed and test it myself later on this weekend or something. Have you tried on other machines? Sometimes that can change things too. I'd be testing in Linux, assuming Eagle supports that.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Tested on Windows and Linux, that's all I have access to. Does the exact same thing, whether in Windows 10, or OpenSUSE 44.

It currently builds with C::B and MinGW/GCC and needs allegro installed either in the root directory in a folder called allegro or in usr/local/lib, or in your compiler directory (eww).

This is probably paranoid, but I suspect it's a heisenbug or memory corruption or something. I tried to rule out race conditions by creating a EagleLogGuard, which seems to be working fine to serialize log output.

EDIT
There is some hanky panky going on in my code somewhere....

If I add in this line :

https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/backends/Allegro5/Allegro5WindowManager.cpp#L38

   EAGLE_ASSERT(al_is_event_source_registered(window_queue , &(a5man->window_event_source)));

It passes the assert when closing the window, but then immediately fails the assert. Something is "un-registering" my window_event_source from the window queue.

There's also something fishy here in my log :

EAGLE INFO     : Allegro5WindowManager::AddDisplay - adding ALLEGRO_DISPLAY* 0420c2e0 .
...
EAGLE INFO     : A5WindowManagerProcess : Closing display 0420a0b0

I only ever created one display! Why is their address different?

bamccaig
Member #7,536
July 2006
avatar

Edgar Reynaldo
Member #8,592
May 2007
avatar

I found the issue. ::)

Super facepalm here.

Look at the highlighted lines :
https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/backends/Allegro5/Allegro5WindowManager.cpp#L56-L66

#SelectExpand
1diff --git a/src/backends/Allegro5/Allegro5WindowManager.cpp b/src/backends/Allegro5/Allegro5WindowManager.cpp 2index c502bc6..ff83399 100644 3--- a/src/backends/Allegro5/Allegro5WindowManager.cpp 4+++ b/src/backends/Allegro5/Allegro5WindowManager.cpp 5@@ -52,10 +52,18 @@ void* A5WindowManagerProcess(EagleThread* thread , void* manager) { 6 break; 7 } 8 else if (ev.type == EAGLE_EVENT_WM_CLOSE_WINDOW) { 9+ 10+ Allegro5GraphicsContext* win = (Allegro5GraphicsContext*)ev.user.data1; 11+ EAGLE_ASSERT(win); 12+ ALLEGRO_DISPLAY* d = win->AllegroDisplay(); 13+ EAGLE_ASSERT(d); 14+ 15 EagleInfo() << "EAGLE_EVENT_WM_CLOSE_WINDOW received by A5WindowManagerProcess" << std::endl; 16- EagleInfo() << StringPrintF("A5WindowManagerProcess : Closing display %p" , ev.display.source) << std::endl; 17+/// EagleInfo() << StringPrintF("A5WindowManagerProcess : Closing display %p" , ev.display.source) << std::endl; 18+ EagleInfo() << StringPrintF("A5WindowManagerProcess : Closing display %p" , d) << std::endl; 19 20- al_unregister_event_source(window_queue , al_get_display_event_source(ev.display.source)); 21+/// al_unregister_event_source(window_queue , al_get_display_event_source(ev.display.source)); 22+ al_unregister_event_source(window_queue , al_get_display_event_source(d)); 23 24 Allegro5GraphicsContext* window = (Allegro5GraphicsContext*)ev.user.data1; 25 EAGLE_ASSERT(window);

The event I was sending for EAGLE_EVENT_WM_CLOSE_WINDOW was a user event not a display event, but I was accessing ev.display.source, which was garbage (or in this case happened to be the same as &window_event_source, which un-registered it from the queue and prevented the EAGLE_EVENT_WM_DESTROY message to be received. This has taken me weeks to find. :'(

Elias
Member #358
May 2000

Thanks for updating us on that! Just one of those bugs...

Maybe we should add a function:

ALLEGRO_DISPLAY_EVENT *al_get_display_event(ALLEGRO_EVENT *event);

And it would return NULL if the event is not a display event, and otherwise the display event. And the same for all the other event types. And we could deprecate direct access to the ALLEGRO_EVENT structur and you would instead use:

al_get_display_event_source(al_get_display_event(ev))

Which would crash if the event is the wrong type, and so you would have immediately found this bug. Direct struct access of a union in C++ is bad :P

--
"Either help out or stop whining" - Evert

bamccaig
Member #7,536
July 2006
avatar

Edgar Reynaldo
Member #8,592
May 2007
avatar

EDIT

I think all the problems are solved (with window destruction at least). Test program now successfully creates and destroys windows on command.

Drawing is another matter.

Build is stable and fixed if you want to try things out bammccaig.

git clone https://github.com/EdgarReynaldo/EagleGUI.git

EDIT2

Drawing text is still messed up. Only the most recently loaded font shows up when drawing to multiple windows.

EDIT3

A clean example of multiple windows works fine when using strictly allegro. Text gets drawn normally.

https://github.com/EdgarReynaldo/EagleGUI/blob/master/src/tests/AllegroMultiWin.hpp

Go to: