From: <ebo...@us...> - 2003-09-26 12:30:20
|
Update of /cvsroot/alleg/allegro/src/unix In directory sc8-pr-cvs1:/tmp/cvs-serv1001/src/unix Modified Files: Tag: allegro_4_0_branch usystem.c uthreads.c Log Message: Backported from 4.1.x: - Sam Hocevar fixed a race condition in the mixer. - Added synchronization routines on multi-threaded platforms. Index: usystem.c =================================================================== RCS file: /cvsroot/alleg/allegro/src/unix/usystem.c,v retrieving revision 1.18.2.1 retrieving revision 1.18.2.2 diff -u -d -r1.18.2.1 -r1.18.2.2 --- usystem.c 23 Dec 2002 00:06:08 -0000 1.18.2.1 +++ usystem.c 26 Sep 2003 12:30:14 -0000 1.18.2.2 @@ -57,6 +57,26 @@ +/* auxilliary system driver */ +#ifdef HAVE_LIBPTHREAD + +SYSTEM_DRIVER_AUX unix_system_driver_aux = { + _unix_create_mutex, + _unix_destroy_mutex, + _unix_lock_mutex, + _unix_unlock_mutex +}; + +SYSTEM_DRIVER_AUX *_al_system_driver_aux = &unix_system_driver_aux; + +#else + +SYSTEM_DRIVER_AUX *_al_system_driver_aux = NULL; + +#endif + + + /* background function manager */ struct bg_manager *_unix_bg_man; Index: uthreads.c =================================================================== RCS file: /cvsroot/alleg/allegro/src/unix/uthreads.c,v retrieving revision 1.7.2.2 retrieving revision 1.7.2.3 diff -u -d -r1.7.2.2 -r1.7.2.3 --- uthreads.c 22 May 2002 04:57:36 -0000 1.7.2.2 +++ uthreads.c 26 Sep 2003 12:30:14 -0000 1.7.2.3 @@ -12,6 +12,8 @@ * * By George Foot and Peter Wang. * + * Synchronization functions added by Eric Botcazou. + * * See readme.txt for copyright information. */ @@ -213,6 +215,86 @@ bg_man_pthreads_disable_interrupts, bg_man_pthreads_interrupts_disabled }; + + + +/* custom mutex that supports nested locking */ +struct my_mutex { + int lock_count; /* level of nested locking */ + pthread_t owner; /* thread which owns the mutex */ + pthread_mutex_t actual_mutex; /* underlying mutex object */ +}; + + + +/* _unix_create_mutex: + * Creates a mutex and returns a pointer to it. + */ +void *_unix_create_mutex (void) +{ + struct my_mutex *mx; + + mx = malloc (sizeof (struct my_mutex)); + if (!mx) { + *allegro_errno = ENOMEM; + return NULL; + } + + mx->lock_count = 0; + mx->owner = (pthread_t) 0; + + pthread_mutex_init (&mx->actual_mutex, NULL); + + return (void *) mx; +} + + + +/* _unix_destroy_mutex: + * Destroys a mutex. + */ +void _unix_destroy_mutex (void *handle) +{ + struct my_mutex *mx = (struct my_mutex *) handle; + + pthread_mutex_destroy (&mx->actual_mutex); + + free (mx); +} + + + +/* _unix_lock_mutex: + * Locks a mutex. + */ +void _unix_lock_mutex (void *handle) +{ + struct my_mutex *mx = (struct my_mutex *) handle; + + if (mx->owner != pthread_self ()) { + pthread_mutex_lock (&mx->actual_mutex); + mx->owner = pthread_self (); + } + + mx->lock_count++; +} + + + +/* _unix_unlock_mutex: + * Unlocks a mutex. + */ +void _unix_unlock_mutex (void *handle) +{ + struct my_mutex *mx = (struct my_mutex *) handle; + + mx->lock_count--; + + if (mx->lock_count == 0) { + mx->owner = (pthread_t) 0; + pthread_mutex_unlock (&mx->actual_mutex); + } +} #endif |