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