Access Violation in al_flip_display with threads
schollexpos

I have started programming a multithreaded game, which has 3 threads: - Drawing - Updating - Main (started the other two, event handling etc.) And my problem occurs in the drawing thread:

#SelectExpand
1void *windowThread(ALLEGRO_THREAD *thread, void* arg) { 2 void **arguments = (void**)arg; 3 ALLEGRO_DISPLAY *display; 4 5 DrawList *drawList = ((DrawList*)arguments[0]); 6 ALLEGRO_EVENT_QUEUE *eventQueue = ((ALLEGRO_EVENT_QUEUE*)arguments[1]); 7 8 display = al_create_display(1280, 720); 9 al_register_event_source(eventQueue, al_get_display_event_source(display)); 10 11 while (!al_get_thread_should_stop(thread)) { 12 drawlist::List *drawbuffer = drawList->getScreenList(); 13 while(drawbuffer->consume()) { 14 //...Draw Stuff... 15 } 16 drawList->ready(drawbuffer); 17 al_flip_display(); 18 } 19 20 return nullptr; 21 }

drawList just keeps two pointers to drawlist::Lists, one for the update thread to be filled, and one for the drawing thread to be drawn and upon calling drawList->ready() it blocks with an ALLEGRO_COND until the other thread has also called ready, then the two pointers are swapped so that upon the next call of getScreenList() it returns the other list, that was previously filled in by the update thread. And now the problem: In al_flip_display() (display.c 190) the call to al_get_current_display() fails, because the threadlocalstate from which it gets the display (tlc.c 396) is "0x323F800000" which causes an access violation.

Total suprise: The problem wasn't actually caused by allegro but instead by some other thing which had a buffer overflow.

Erin Maus

Total suprise: The problem wasn't actually caused by allegro but instead by some other thing which had a buffer overflow.

Ah, the best kind of bug. :)

I remember many nights spent debugging those sort of errors...

Edgar Reynaldo

You'll want to be careful using a display in another thread like that. There are certain things you need to be aware of.

You will only get hw accelerated drawing on bitmaps created, or converted on that thread when that display is current. So if you load or create bitmaps in another thread they must be converted to the proper format before you get acceleration.

You can make sure they are loaded in the right format by 1) loading them in the same thread as the one that created the display, or 2) by cheating and setting the target bitmap to the backbuffer of the display created on that thread. That would make that thread and display current for loading and creation purposes. You would need to un set the current display for that thread when you were done then, and re-set it for the display thread.

Thread #617754. Printed from Allegro.cc