Re: [AD] timer_mutex again

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Eric Botcazou wrote:

On the debug, C-only, X11 port of Allegro I can easily get a deadlock
when grabber starts up.  At some stage, show_mouse(NULL) is called,
which calls remove_int(), which locks the timer_mutex in timer.c, but
the timer_mutex is already locked by _handle_timer_tick() while it tries
to fire off timer callback functions.  Sound familiar?

Why does it deadlock in the end?

This is gdb on tools/grabber. It deadlocks immediately on startup so I press ^C.


Program received signal SIGINT, Interrupt.
[Switching to Thread 16384 (LWP 27080)]
0x400529f3 in __pthread_sigsuspend () from /lib/libpthread.so.0
(gdb) bt
#0  0x400529f3 in __pthread_sigsuspend () from /lib/libpthread.so.0
#1 0x40051f88 in __pthread_wait_for_restart_signal () from /lib/libpthread.so.0
#2  0x400541ac in __pthread_alt_lock () from /lib/libpthread.so.0
#3  0x40050a95 in pthread_mutex_lock () from /lib/libpthread.so.0
#4 0x080d8ddc in _unix_lock_mutex (handle=0x8150658) at src/unix/uthreads.c:361
#5  0x080a08eb in remove_timer_int (proc=0x8096516, param=0x0, param_used=0)
   at src/timer.c:445
#6 0x080a098e in remove_int (proc=0x8096516 <mouse_move>) at src/timer.c:468
#7  0x08096b74 in show_mouse (bmp=0x0) at src/mouse.c:592
#8  0x08096e1a in scare_mouse () at src/mouse.c:678
#9 0x0808256e in object_message (dialog=0x8105140, msg=3, c=0) at src/gui.c:332 #10 0x08082709 in dialog_message (dialog=0x8105140, msg=3, c=0, obj=0x815df90)
   at src/gui.c:393
#11 0x08083836 in check_for_redraw (player=0x815df90) at src/gui.c:1001
#12 0x08084840 in update_dialog (player=0x815df90) at src/gui.c:1287
#13 0x08083197 in do_dialog (dialog=0x8105140, focus_obj=48) at src/gui.c:787
#14 0x080550fc in main (argc=1, argv=0xbffff334) at tools/grabber.c:3822

(gdb) thread 4
[Switching to thread 4 (Thread 32771 (LWP 27084))]#0 0x400529f3 in __pthread_sigsuspend () from /lib/libpthread.so.0
(gdb) bt
#0  0x400529f3 in __pthread_sigsuspend () from /lib/libpthread.so.0
#1 0x40051f88 in __pthread_wait_for_restart_signal () from /lib/libpthread.so.0
#2  0x400541ac in __pthread_alt_lock () from /lib/libpthread.so.0
#3  0x40050a95 in pthread_mutex_lock () from /lib/libpthread.so.0
#4 0x080d8ddc in _unix_lock_mutex (handle=0x81377a0) at src/unix/uthreads.c:361
#5  0x080e9360 in _xwin_lock (bmp=0x815ad80) at src/x/xvtable.c:265
#6  0x0808c695 in acquire_bitmap (bmp=0x815ad80) at gfx.inl:203
#7  0x080965ab in mouse_move () at src/mouse.c:348
#8  0x080a01ca in _handle_timer_tick (interval=11933) at src/timer.c:108
#9  0x080d8783 in ptimer_thread_func (unused=0x0) at src/unix/uptimer.c:140
#10 0x4005054e in pthread_start_thread () from /lib/libpthread.so.0
#11 0x400505df in pthread_start_thread_event () from /lib/libpthread.so.0
#12 0x40252b8a in clone () from /lib/libc.so.6


So thread 4 is holding the timer_mutex in _handle_timer_tick() and wanting to get the _xwin.mutex. Meanwhile thread 1 has the _xwin.mutex (due to an acquire_screen in dialog_message) and wants the timer_mutex.

I'm not so sure. IIRC I added the timer mutex because of the following situation:

void callback(void)
{
 /* dereference pointer p */
}

remove_int (callback);
p = NULL;

The idea was to make sure that all callbacks have completed before remove_int returns. Does your proposed change still guarantee that?

No :-( Actually, the same problem is marked FIXME in the new_api_branch so I should have remembered it.

Peter




Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/