mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
This commit merges the glib-threads branch into the main
branch. See the ChangeLog for details of the changes. In brief overview: - The set of threading functions can be set - A default implementation is provided in -lgthread - All static data structures are locked using these functions if g_thread_init() is called.
This commit is contained in:
parent
c8ba100dab
commit
931ea95265
84
ChangeLog
84
ChangeLog
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,3 +1,87 @@
|
||||
1998-12-11 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/gthread-nspr.c, configure.in: Added new default thread
|
||||
implementation on top of the mozilla nspr library.
|
||||
|
||||
* gmem.c, gmessaged.c, gthread/gthread.c, gthread/gthread-*.c:
|
||||
Changed GStaticMutex and GStaticPrivate in gmem.c and gmessages.c
|
||||
into GMutex and GPrivate resp. to make error reporting and use of
|
||||
gmem possible in most (not all, though) gthread functions. Also
|
||||
initialized the modules via new init functions.
|
||||
|
||||
* configure.in: Fixed syntax bug in definition of type
|
||||
GStaticMutex.
|
||||
|
||||
* gthread/testgthread.c: Updated to work with nspr, but see note
|
||||
there for remaining problems.
|
||||
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmutex.c, glib.h: Now abort, if a mutex/cond/private is
|
||||
allocated before the thread system is set up.
|
||||
|
||||
* gthread/gthread.c (g_thread_init): Removed g_thread_try_init(),
|
||||
as it is not necessary. Changed the error message. Corrected logic
|
||||
for g_thread_use_default_impl.
|
||||
|
||||
* gmutex.c (g_mutex_init): Keep the thread private data array
|
||||
after calling g_thread_init().
|
||||
|
||||
1998-12-09 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gthread/testgthread.c (new_thread): Now also working for posix
|
||||
threads; (wait_thread): Now a better implementation, that does not
|
||||
use 100% CPU.
|
||||
|
||||
* Made the thread related code follow GNU coding standard.
|
||||
|
||||
* Made a comment (HOLDS:) above each function, that expects the
|
||||
given locks to be held.
|
||||
|
||||
* Changed try_lock to trylock throughout.
|
||||
|
||||
* glib.c: Eventually removed the #if 0'ed code for old GStaticMutex.
|
||||
|
||||
* glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS.
|
||||
|
||||
* gmain.c (g_main_poll_add_unlocked): first take a new poll record
|
||||
form the poll_free_list.
|
||||
|
||||
* gmem.c, gstrfuncs.c, gutils.c: Made it MT safe.
|
||||
|
||||
* gthraed/*.c: Added copyright headers.
|
||||
|
||||
* gthread/gthread-solaris.c: do not use g_log for errors, as g_log
|
||||
uses these module and endless recursions might happen, just use a
|
||||
plain fprintf(stderr,...).
|
||||
|
||||
* gthread/gthread.c (g_thread_try_init): Call g_mutex_init().
|
||||
|
||||
* gthread/testgthread.c: updated test program.
|
||||
|
||||
Tue Dec 8 18:49:56 1998 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* Start at adding thread-safety. (mostly work
|
||||
of Sebastian Wilhelmi <wilhelmi@ira.uka.de>)
|
||||
|
||||
- configure.in now looks for a system thread implementation.
|
||||
Currently support is included for POSIX threads
|
||||
and Solaris threads. The default support is built
|
||||
into a separate library -lgthread.
|
||||
|
||||
- The thread implementation can be modified by passing
|
||||
a vector of functions g_thread_init().
|
||||
|
||||
- The default or supplied functions are used to
|
||||
implement a small set of thread functions for
|
||||
mutexes, condition variables, and thread-private
|
||||
data.
|
||||
|
||||
- GLib now uses these functions to provide thread
|
||||
safety. (In the sense that all global static
|
||||
data is locked... individual structures must still
|
||||
be locked by the caller.)
|
||||
|
||||
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||
|
@ -1,7 +1,7 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# build . first, then SUBDIRS
|
||||
SUBDIRS = gmodule docs
|
||||
SUBDIRS = gmodule gthread docs
|
||||
all-recursive-am: all-am
|
||||
# alpha `automake' supports this better
|
||||
#SUBDIRS = . gmodule docs
|
||||
@ -50,7 +50,8 @@ libglib_la_SOURCES = \
|
||||
gstring.c \
|
||||
gstrfuncs.c \
|
||||
gscanner.c \
|
||||
gutils.c
|
||||
gutils.c \
|
||||
gmutex.c
|
||||
|
||||
include_HEADERS = \
|
||||
glib.h
|
||||
|
@ -84,6 +84,8 @@
|
||||
#undef WIN32
|
||||
#undef NATIVE_WIN32
|
||||
|
||||
#undef G_THREAD_SOURCE
|
||||
|
||||
/* #undef PACKAGE */
|
||||
/* #undef VERSION */
|
||||
|
||||
|
206
configure.in
206
configure.in
@ -508,6 +508,155 @@ AC_SUBST(G_MODULE_HAVE_DLERROR)
|
||||
AC_SUBST(G_MODULE_NEED_USCORE)
|
||||
AC_SUBST(GLIB_DEBUG_FLAGS)
|
||||
|
||||
|
||||
dnl ***********************
|
||||
dnl *** g_thread checks ***
|
||||
dnl ***********************
|
||||
|
||||
AC_ARG_WITH(threads, [ --with-threads=[none/posix/solaris/nspr] specify a thread implementation to use.],,)
|
||||
|
||||
dnl error and warning message
|
||||
dnl *************************
|
||||
|
||||
THREAD_NO_IMPLEMENTATION="You do not have any known thread system on your
|
||||
computer. glib will not be thread safe on your computer."
|
||||
|
||||
THREAD_UNKNOWN_COMPILER="Your compiler is not known, so I cannot
|
||||
determine the necessary compiler options to compile programs
|
||||
which are using threads. Please provide such information."
|
||||
|
||||
FLAG_DOES_NOT_WORK="I can't find the MACRO, that enables thread safety on your
|
||||
platform (normaly it's "_REENTRANT"). I'll not use any flag on
|
||||
compilation now, but then your programs might not work.
|
||||
Please provide information on how it is done on your system."
|
||||
|
||||
LIBS_NOT_FOUND_1="I can't find the libraries for the thread implementation
|
||||
"
|
||||
|
||||
LIBS_NOT_FOUND_2=". Please choose another thread implementation or
|
||||
provide informationon your thread implementation."
|
||||
|
||||
dnl determination of thread implementation
|
||||
dnl ***************************************
|
||||
|
||||
if test x"$with_threads" = x; then
|
||||
case $host in
|
||||
*-*-solaris*)
|
||||
AC_CHECK_LIB(thread,cond_init,with_threads=solaris)
|
||||
;;
|
||||
esac
|
||||
if test x"$with_threads" = x; then
|
||||
AC_CHECK_LIB(pthread,pthread_cond_init,with_threads=posix)
|
||||
AC_CHECK_LIB(pthreads,pthread_attr_init,with_threads=posix)
|
||||
AC_CHECK_LIB(nspr21,PRP_NewNakedCondVar,with_threads=nspr)
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for thread implementation)
|
||||
|
||||
if test x"$with_threads" = x; then
|
||||
with_threads=none
|
||||
AC_MSG_WARN($THREAD_NO_IMPLEMENTATION)
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT($with_threads)
|
||||
|
||||
dnl determination of G_THREAD_LIBS
|
||||
dnl ******************************
|
||||
|
||||
G_THREAD_LIBS=
|
||||
|
||||
case $with_threads in
|
||||
posix)
|
||||
G_THREAD_LIBS=error
|
||||
AC_CHECK_LIB(pthreads,pthread_cond_init,
|
||||
G_THREAD_LIBS="-lpthreads")
|
||||
AC_CHECK_LIB(pthread,pthread_cond_init,
|
||||
G_THREAD_LIBS="-lpthread")
|
||||
;;
|
||||
solaris)
|
||||
G_THREAD_LIBS=error
|
||||
AC_CHECK_LIB(thread,cond_init,G_THREAD_LIBS="-lthread")
|
||||
# solaris has a broken initializer for mutexes, if we find it,
|
||||
# we will replace it.
|
||||
AC_MSG_CHECKING(for broken solaris mutex initialization)
|
||||
AC_EGREP_CPP([ *begin *{ *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *, *0 *} *end *],
|
||||
[#include <thread.h>
|
||||
begin DEFAULTMUTEX end],
|
||||
[solaris_mutex_init_broken=yes],
|
||||
[solaris_mutex_init_broken=no])
|
||||
AC_MSG_RESULT($solaris_mutex_init_broken)
|
||||
;;
|
||||
nspr)
|
||||
AC_CHECK_LIB(nspr21,PRP_NewNakedCondVar,
|
||||
G_THREAD_LIBS="-lnspr21")
|
||||
;;
|
||||
none)
|
||||
;;
|
||||
*)
|
||||
G_THREAD_LIBS=error
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$G_THREAD_LIBS" = xerror; then
|
||||
AC_MSG_ERROR($LIBS_NOT_FOUND_1$with_threads$LIBS_NOT_FOUND_2)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(necessary linker options)
|
||||
AC_MSG_RESULT($G_THREAD_LIBS)
|
||||
|
||||
dnl determination of G_THREAD_CFLAGS
|
||||
dnl ********************************
|
||||
|
||||
if test x"$with_threads" != xnone; then
|
||||
G_THREAD_CFLAGS="-D_REENTRANT" # good default
|
||||
|
||||
case $host in
|
||||
-aix*)
|
||||
# FIXME: can somebody confirm this -D_THREAD_SAFE ???
|
||||
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -D_THREAD_SAFE"
|
||||
if test x"$GCC" = xyes; then
|
||||
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -mthreads"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# if we are not finding the ctime_r function, then we probably are
|
||||
# not using the proper multithread flag
|
||||
old_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $G_THREAD_CFLAGS"
|
||||
AC_EGREP_HEADER([[^a-zA-Z_]ctime_r[^a-zA-Z_]], time.h, ,
|
||||
G_THREAD_CFLAGS=
|
||||
AC_MSG_WARN($FLAG_DOES_NOT_WORK))
|
||||
CPPFLAGS=$old_CPPFLAGS
|
||||
|
||||
if test x"$GCC" = xyes; then
|
||||
# older gcc's do not know the -fstack-check option and will
|
||||
# stop compiling, so just check this here
|
||||
old_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS -fstack-check"
|
||||
AC_TRY_COMPILE(,,
|
||||
G_THREAD_CFLAGS="$G_THREAD_CFLAGS -fstack-check")
|
||||
CPPFLAGS=$old_CPPFLAGS
|
||||
else
|
||||
AC_MSG_WARN($THREAD_UNKNOWN_COMPILER)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(necessary compiler options)
|
||||
|
||||
AC_MSG_RESULT($G_THREAD_CFLAGS)
|
||||
else
|
||||
G_THREAD_CFLAGS=
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(G_THREAD_SOURCE,"gthread-$with_threads.c")
|
||||
AC_SUBST(G_THREAD_CFLAGS)
|
||||
AC_SUBST(G_THREAD_LIBS)
|
||||
|
||||
dnl ******************************
|
||||
dnl *** output the whole stuff ***
|
||||
dnl ******************************
|
||||
|
||||
AC_OUTPUT_COMMANDS([
|
||||
|
||||
## Generate `glibconfig.h' in two cases
|
||||
@ -550,6 +699,9 @@ outfile_EOF
|
||||
if test x$glib_values_h = xyes; then
|
||||
echo '#include <values.h>' >> $outfile
|
||||
fi
|
||||
if test x$g_mutex_header_file != x; then
|
||||
echo '#include <'"$g_mutex_header_file"'>' >> $outfile
|
||||
fi
|
||||
if test x$glib_sys_poll_h = xyes; then
|
||||
echo '#include <sys/types.h>' >> $outfile
|
||||
echo '#include <sys/poll.h>' >> $outfile
|
||||
@ -628,6 +780,34 @@ $glib_inline
|
||||
#define G_BYTE_ORDER $g_byte_order
|
||||
outfile_EOF
|
||||
|
||||
cat >>$outfile <<outfile_EOF
|
||||
|
||||
/* definitions for the default mutex implementation */
|
||||
outfile_EOF
|
||||
|
||||
if test x$g_mutex_has_default = xyes; then
|
||||
cat >>$outfile <<outfile_EOF
|
||||
|
||||
typedef struct _GStaticMutex GStaticMutex;
|
||||
struct _GStaticMutex
|
||||
{
|
||||
$g_mutex_default_type default_mutex;
|
||||
struct _GMutex* runtime_mutex;
|
||||
};
|
||||
#define G_STATIC_MUTEX_INIT { $g_mutex_default_init, NULL }
|
||||
#define g_static_mutex_get_mutex(mutex) \
|
||||
( g_thread_use_default_impl ? (GMutex*)&mutex.default_mutex : \
|
||||
g_static_mutex_get_mutex_impl(&mutex.runtime_mutex) )
|
||||
outfile_EOF
|
||||
else
|
||||
cat >>$outfile <<outfile_EOF
|
||||
|
||||
typedef struct _GMutex* GStaticMutex;
|
||||
#define G_STATIC_MUTEX_INIT NULL
|
||||
#define g_static_mutex_get_mutex(mutex) g_static_mutex_get_mutex_impl(&mutex)
|
||||
outfile_EOF
|
||||
fi
|
||||
|
||||
g_bit_sizes="16 32"
|
||||
if test -n "$gint64"; then
|
||||
g_bit_sizes="$g_bit_sizes 64"
|
||||
@ -841,6 +1021,31 @@ if test x$glib_working_wctype = xno; then
|
||||
glib_wc="\$glib_wc
|
||||
#define G_HAVE_BROKEN_WCTYPE 1"
|
||||
fi
|
||||
|
||||
case $with_threads in
|
||||
posix)
|
||||
g_mutex_has_default=yes
|
||||
g_mutex_default_type='pthread_mutex_t'
|
||||
g_mutex_default_init='PTHREAD_MUTEX_INITIALIZER'
|
||||
g_mutex_header_file='pthread.h'
|
||||
;;
|
||||
solaris)
|
||||
g_mutex_has_default=yes
|
||||
g_mutex_default_type='mutex_t'
|
||||
if test x$solaris_mutex_init_broken = xyes; then
|
||||
g_mutex_default_init="{ { { 0, 0, 0, 0 }, USYNC_THREAD }, { { { 0, 0, 0, 0, 0, 0, 0, 0 } } }, 0}"
|
||||
else
|
||||
g_mutex_default_init="DEFAULTMUTEX"
|
||||
fi
|
||||
g_mutex_header_file='thread.h'
|
||||
;;
|
||||
nspr)
|
||||
g_mutex_has_default=no
|
||||
;;
|
||||
*)
|
||||
g_mutex_has_default=no
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
||||
AC_OUTPUT([
|
||||
@ -848,6 +1053,7 @@ Makefile
|
||||
glib-config
|
||||
gmodule/gmoduleconf.h
|
||||
gmodule/Makefile
|
||||
gthread/Makefile
|
||||
docs/Makefile
|
||||
],[case "$CONFIG_FILES" in
|
||||
*glib-config*)chmod +x glib-config;;
|
||||
|
19
garray.c
19
garray.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glib.h"
|
||||
|
||||
@ -40,9 +45,8 @@ static gint g_nearest_pow (gint num);
|
||||
static void g_array_maybe_expand (GRealArray *array,
|
||||
gint len);
|
||||
|
||||
|
||||
static GMemChunk *array_mem_chunk = NULL;
|
||||
|
||||
static G_LOCK_DEFINE(array_mem_chunk);
|
||||
|
||||
GArray*
|
||||
g_array_new (gboolean zero_terminated,
|
||||
@ -51,12 +55,14 @@ g_array_new (gboolean zero_terminated,
|
||||
{
|
||||
GRealArray *array;
|
||||
|
||||
g_lock (array_mem_chunk);
|
||||
if (!array_mem_chunk)
|
||||
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||
sizeof (GRealArray),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
array = g_chunk_new (GRealArray, array_mem_chunk);
|
||||
g_unlock (array_mem_chunk);
|
||||
|
||||
array->data = NULL;
|
||||
array->len = 0;
|
||||
@ -75,7 +81,9 @@ g_array_free (GArray *array,
|
||||
if (free_segment)
|
||||
g_free (array->data);
|
||||
|
||||
g_lock (array_mem_chunk);
|
||||
g_mem_chunk_free (array_mem_chunk, array);
|
||||
g_unlock (array_mem_chunk);
|
||||
}
|
||||
|
||||
GArray*
|
||||
@ -241,9 +249,8 @@ struct _GRealPtrArray
|
||||
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||
gint len);
|
||||
|
||||
|
||||
static GMemChunk *ptr_array_mem_chunk = NULL;
|
||||
|
||||
static G_LOCK_DEFINE(ptr_array_mem_chunk);
|
||||
|
||||
|
||||
GPtrArray*
|
||||
@ -251,12 +258,14 @@ g_ptr_array_new (void)
|
||||
{
|
||||
GRealPtrArray *array;
|
||||
|
||||
g_lock (ptr_array_mem_chunk);
|
||||
if (!ptr_array_mem_chunk)
|
||||
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||
sizeof (GRealPtrArray),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
||||
g_unlock (ptr_array_mem_chunk);
|
||||
|
||||
array->pdata = NULL;
|
||||
array->len = 0;
|
||||
@ -274,7 +283,9 @@ g_ptr_array_free (GPtrArray *array,
|
||||
if (free_segment)
|
||||
g_free (array->pdata);
|
||||
|
||||
g_lock (ptr_array_mem_chunk);
|
||||
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
||||
g_unlock (ptr_array_mem_chunk);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -17,6 +17,11 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||
* then
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
11
gcache.c
11
gcache.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -56,7 +61,7 @@ static void g_cache_node_destroy (GCacheNode *node);
|
||||
|
||||
|
||||
static GMemChunk *node_mem_chunk = NULL;
|
||||
|
||||
static G_LOCK_DEFINE(node_mem_chunk);
|
||||
|
||||
GCache*
|
||||
g_cache_new (GCacheNewFunc value_new_func,
|
||||
@ -193,11 +198,13 @@ g_cache_node_new (gpointer value)
|
||||
{
|
||||
GCacheNode *node;
|
||||
|
||||
g_lock (node_mem_chunk);
|
||||
if (!node_mem_chunk)
|
||||
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
node = g_chunk_new (GCacheNode, node_mem_chunk);
|
||||
g_unlock (node_mem_chunk);
|
||||
|
||||
node->value = value;
|
||||
node->ref_count = 1;
|
||||
@ -208,5 +215,7 @@ g_cache_node_new (gpointer value)
|
||||
static void
|
||||
g_cache_node_destroy (GCacheNode *node)
|
||||
{
|
||||
g_lock (node_mem_chunk);
|
||||
g_mem_chunk_free (node_mem_chunk, node);
|
||||
g_unlock (node_mem_chunk);
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <string.h>
|
||||
|
||||
|
76
gdataset.c
76
gdataset.c
@ -18,6 +18,12 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe ; FIXME: might still freeze, watch out, not thoroughly
|
||||
* looked at yet.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glib.h"
|
||||
|
||||
@ -61,18 +67,24 @@ static inline GQuark g_quark_new (gchar *string);
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
static G_LOCK_DEFINE(g_dataset_global);
|
||||
static GHashTable *g_dataset_location_ht = NULL;
|
||||
static GDataset *g_dataset_cached = NULL;
|
||||
static GDataset *g_dataset_cached = NULL; /* should this be
|
||||
threadspecific? */
|
||||
static GMemChunk *g_dataset_mem_chunk = NULL;
|
||||
static GMemChunk *g_data_mem_chunk = NULL;
|
||||
static GData *g_data_cache = NULL;
|
||||
static guint g_data_cache_length = 0;
|
||||
|
||||
static G_LOCK_DEFINE(g_quark_global);
|
||||
static GHashTable *g_quark_ht = NULL;
|
||||
static gchar **g_quarks = NULL;
|
||||
static GQuark g_quark_seq_id = 0;
|
||||
|
||||
|
||||
/* --- functions --- */
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static inline void
|
||||
g_datalist_clear_i (GData **datalist)
|
||||
{
|
||||
@ -109,13 +121,16 @@ g_datalist_clear (GData **datalist)
|
||||
{
|
||||
g_return_if_fail (datalist != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (!g_dataset_location_ht)
|
||||
g_data_initialize ();
|
||||
|
||||
while (*datalist)
|
||||
g_datalist_clear_i (datalist);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static inline GDataset*
|
||||
g_dataset_lookup (gconstpointer dataset_location)
|
||||
{
|
||||
@ -131,6 +146,7 @@ g_dataset_lookup (gconstpointer dataset_location)
|
||||
return dataset;
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static void
|
||||
g_dataset_destroy_internal (GDataset *dataset)
|
||||
{
|
||||
@ -158,6 +174,7 @@ g_dataset_destroy (gconstpointer dataset_location)
|
||||
{
|
||||
g_return_if_fail (dataset_location != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (g_dataset_location_ht)
|
||||
{
|
||||
register GDataset *dataset;
|
||||
@ -166,8 +183,10 @@ g_dataset_destroy (gconstpointer dataset_location)
|
||||
if (dataset)
|
||||
g_dataset_destroy_internal (dataset);
|
||||
}
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static inline void
|
||||
g_data_set_internal (GData **datalist,
|
||||
GQuark key_id,
|
||||
@ -293,9 +312,10 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
|
||||
return;
|
||||
}
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (!g_dataset_location_ht)
|
||||
g_data_initialize ();
|
||||
|
||||
|
||||
dataset = g_dataset_lookup (dataset_location);
|
||||
if (!dataset)
|
||||
{
|
||||
@ -308,6 +328,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
|
||||
}
|
||||
|
||||
g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
void
|
||||
@ -327,10 +348,12 @@ g_datalist_id_set_data_full (GData **datalist,
|
||||
return;
|
||||
}
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (!g_dataset_location_ht)
|
||||
g_data_initialize ();
|
||||
|
||||
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
void
|
||||
@ -339,6 +362,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
||||
{
|
||||
g_return_if_fail (dataset_location != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (key_id && g_dataset_location_ht)
|
||||
{
|
||||
GDataset *dataset;
|
||||
@ -346,7 +370,8 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
||||
dataset = g_dataset_lookup (dataset_location);
|
||||
if (dataset)
|
||||
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
|
||||
}
|
||||
}
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
void
|
||||
@ -355,8 +380,10 @@ g_datalist_id_remove_no_notify (GData **datalist,
|
||||
{
|
||||
g_return_if_fail (datalist != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (key_id && g_dataset_location_ht)
|
||||
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
gpointer
|
||||
@ -365,6 +392,7 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
||||
{
|
||||
g_return_val_if_fail (dataset_location != NULL, NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (key_id && g_dataset_location_ht)
|
||||
{
|
||||
register GDataset *dataset;
|
||||
@ -376,10 +404,14 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
||||
|
||||
for (list = dataset->datalist; list; list = list->next)
|
||||
if (list->id == key_id)
|
||||
return list->data;
|
||||
{
|
||||
g_unlock (g_dataset_global);
|
||||
return list->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_unlock (g_dataset_global);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -411,17 +443,23 @@ g_dataset_foreach (gconstpointer dataset_location,
|
||||
g_return_if_fail (dataset_location != NULL);
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (g_dataset_location_ht)
|
||||
{
|
||||
dataset = g_dataset_lookup (dataset_location);
|
||||
g_unlock (g_dataset_global);
|
||||
if (dataset)
|
||||
{
|
||||
register GData *list;
|
||||
|
||||
for (list = dataset->datalist; list; list = list->next)
|
||||
func (list->id, list->data, user_data);
|
||||
func (list->id, list->data, user_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -446,6 +484,7 @@ g_datalist_init (GData **datalist)
|
||||
*datalist = NULL;
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static void
|
||||
g_data_initialize (void)
|
||||
{
|
||||
@ -468,12 +507,15 @@ g_data_initialize (void)
|
||||
GQuark
|
||||
g_quark_try_string (const gchar *string)
|
||||
{
|
||||
GQuark quark = 0;
|
||||
g_return_val_if_fail (string != NULL, 0);
|
||||
|
||||
g_lock (g_quark_global);
|
||||
if (g_quark_ht)
|
||||
return (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||
else
|
||||
return 0;
|
||||
quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
GQuark
|
||||
@ -483,6 +525,7 @@ g_quark_from_string (const gchar *string)
|
||||
|
||||
g_return_val_if_fail (string != NULL, 0);
|
||||
|
||||
g_lock (g_quark_global);
|
||||
if (g_quark_ht)
|
||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||
else
|
||||
@ -493,6 +536,7 @@ g_quark_from_string (const gchar *string)
|
||||
|
||||
if (!quark)
|
||||
quark = g_quark_new (g_strdup (string));
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return quark;
|
||||
}
|
||||
@ -504,6 +548,7 @@ g_quark_from_static_string (const gchar *string)
|
||||
|
||||
g_return_val_if_fail (string != NULL, 0);
|
||||
|
||||
g_lock (g_quark_global);
|
||||
if (g_quark_ht)
|
||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||
else
|
||||
@ -514,19 +559,24 @@ g_quark_from_static_string (const gchar *string)
|
||||
|
||||
if (!quark)
|
||||
quark = g_quark_new ((gchar*) string);
|
||||
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
gchar*
|
||||
g_quark_to_string (GQuark quark)
|
||||
{
|
||||
gchar* result = NULL;
|
||||
g_lock (g_quark_global);
|
||||
if (quark > 0 && quark <= g_quark_seq_id)
|
||||
return g_quarks[quark - 1];
|
||||
else
|
||||
return NULL;
|
||||
result = g_quarks[quark - 1];
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* HOLDS: g_quark_global_lock */
|
||||
static inline GQuark
|
||||
g_quark_new (gchar *string)
|
||||
{
|
||||
|
24
gdate.c
24
gdate.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
#include <time.h>
|
||||
@ -383,6 +388,8 @@ g_date_clear (GDate *d, guint ndates)
|
||||
memset (d, 0x0, ndates*sizeof (GDate));
|
||||
}
|
||||
|
||||
static G_LOCK_DEFINE(g_date_global);
|
||||
|
||||
/* These are for the parser, output to the user should use *
|
||||
* g_date_strftime () - this creates more never-freed memory to annoy
|
||||
* all those memory debugger users. :-)
|
||||
@ -429,6 +436,7 @@ typedef struct _GDateParseTokens GDateParseTokens;
|
||||
|
||||
#define NUM_LEN 10
|
||||
|
||||
/* HOLDS: g_date_global_lock */
|
||||
static void
|
||||
g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
||||
{
|
||||
@ -488,7 +496,7 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
||||
if (found != NULL)
|
||||
{
|
||||
pt->month = i;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,12 +510,13 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* HOLDS: g_date_global_lock */
|
||||
static void
|
||||
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
|
||||
{
|
||||
@ -641,6 +650,8 @@ g_date_set_parse (GDate *d,
|
||||
/* set invalid */
|
||||
g_date_clear (d, 1);
|
||||
|
||||
g_lock (g_date_global);
|
||||
|
||||
g_date_prepare_to_parse (str, &pt);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -649,7 +660,11 @@ g_date_set_parse (GDate *d,
|
||||
#endif
|
||||
|
||||
|
||||
if (pt.num_ints == 4) return; /* presumably a typo; bail out. */
|
||||
if (pt.num_ints == 4)
|
||||
{
|
||||
g_unlock (g_date_global);
|
||||
return; /* presumably a typo; bail out. */
|
||||
}
|
||||
|
||||
if (pt.num_ints > 1)
|
||||
{
|
||||
@ -765,6 +780,7 @@ g_date_set_parse (GDate *d,
|
||||
else
|
||||
g_message ("Rejected DMY %u %u %u", day, m, y);
|
||||
#endif
|
||||
g_unlock (g_date_global);
|
||||
}
|
||||
|
||||
void
|
||||
|
5
gerror.c
5
gerror.c
@ -17,6 +17,11 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||
* then
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
13
ghash.c
13
ghash.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -52,6 +57,8 @@ static void g_hash_node_destroy (GHashNode *hash_node);
|
||||
static void g_hash_nodes_destroy (GHashNode *hash_node);
|
||||
|
||||
|
||||
static G_LOCK_DEFINE(g_hash_global);
|
||||
|
||||
static GMemChunk *node_mem_chunk = NULL;
|
||||
static GHashNode *node_free_list = NULL;
|
||||
|
||||
@ -338,6 +345,7 @@ g_hash_node_new (gpointer key,
|
||||
{
|
||||
GHashNode *hash_node;
|
||||
|
||||
g_lock (g_hash_global);
|
||||
if (node_free_list)
|
||||
{
|
||||
hash_node = node_free_list;
|
||||
@ -352,6 +360,7 @@ g_hash_node_new (gpointer key,
|
||||
|
||||
hash_node = g_chunk_new (GHashNode, node_mem_chunk);
|
||||
}
|
||||
g_unlock (g_hash_global);
|
||||
|
||||
hash_node->key = key;
|
||||
hash_node->value = value;
|
||||
@ -363,8 +372,10 @@ g_hash_node_new (gpointer key,
|
||||
static void
|
||||
g_hash_node_destroy (GHashNode *hash_node)
|
||||
{
|
||||
g_lock (g_hash_global);
|
||||
hash_node->next = node_free_list;
|
||||
node_free_list = hash_node;
|
||||
g_unlock (g_hash_global);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -380,6 +391,8 @@ g_hash_nodes_destroy (GHashNode *hash_node)
|
||||
while (node->next)
|
||||
node = node->next;
|
||||
|
||||
g_lock (g_hash_global);
|
||||
node->next = node_free_list;
|
||||
node_free_list = hash_node;
|
||||
g_unlock (g_hash_global);
|
||||
}
|
||||
|
5
ghook.c
5
ghook.c
@ -19,6 +19,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
@ -17,6 +17,7 @@ Options:
|
||||
Libraries:
|
||||
glib
|
||||
gmodule
|
||||
gthread
|
||||
EOF
|
||||
exit $1
|
||||
}
|
||||
@ -69,6 +70,9 @@ while test $# -gt 0; do
|
||||
gmodule)
|
||||
lib_gmodule=yes
|
||||
;;
|
||||
gthread)
|
||||
lib_gthread=yes
|
||||
;;
|
||||
*)
|
||||
usage 1 1>&2
|
||||
;;
|
||||
@ -83,7 +87,11 @@ if test "$echo_exec_prefix" = "yes"; then
|
||||
echo $exec_prefix
|
||||
fi
|
||||
if test "$echo_cflags" = "yes"; then
|
||||
echo -I@libdir@/glib/include $includes
|
||||
cflags=""
|
||||
if test "$lib_gthread" = "yes"; then
|
||||
cflags="$cflags @G_THREAD_CFLAGS@"
|
||||
fi
|
||||
echo -I@libdir@/glib/include $includes $cflags
|
||||
fi
|
||||
if test "$echo_libs" = "yes"; then
|
||||
libs=""
|
||||
@ -93,5 +101,8 @@ if test "$echo_libs" = "yes"; then
|
||||
if test "$lib_gmodule" = "yes"; then
|
||||
libs="@G_MODULE_LDFLAGS@ -lgmodule $libs @G_MODULE_LIBS@"
|
||||
fi
|
||||
echo "-L@libdir@ $libs"
|
||||
if test "$lib_gthread" = "yes"; then
|
||||
libs="-lgthread $libs @G_THREAD_LIBS@"
|
||||
fi
|
||||
echo -L@libdir@ $libs
|
||||
fi
|
||||
|
134
glib.h
134
glib.h
@ -2597,6 +2597,140 @@ gint gwin_closedir (DIR *dir);
|
||||
|
||||
#endif /* NATIVE_WIN32 */
|
||||
|
||||
/* functions for thread support for glib. */
|
||||
|
||||
typedef struct _GMutex GMutex;
|
||||
typedef struct _GCond GCond;
|
||||
typedef struct _GPrivate GPrivate;
|
||||
typedef struct _GStaticPrivate GStaticPrivate;
|
||||
|
||||
typedef struct _GThreadFunctions GThreadFunctions;
|
||||
struct _GThreadFunctions
|
||||
{
|
||||
GMutex* (*mutex_new) (void);
|
||||
void (*mutex_lock) (GMutex* mutex);
|
||||
gboolean (*mutex_trylock) (GMutex* mutex);
|
||||
void (*mutex_unlock) (GMutex* mutex);
|
||||
void (*mutex_free) (GMutex* mutex);
|
||||
GCond* (*cond_new) (void);
|
||||
void (*cond_signal) (GCond* cond);
|
||||
void (*cond_broadcast) (GCond* cond);
|
||||
void (*cond_wait) (GCond* cond, GMutex* mutex);
|
||||
gboolean (*cond_timed_wait) (GCond* cond, GMutex* mutex,
|
||||
GTimeVal *end_time);
|
||||
void (*cond_free) (GCond* cond);
|
||||
GPrivate* (*private_new) (GDestroyNotify destructor);
|
||||
gpointer (*private_get) (GPrivate* private);
|
||||
void (*private_set) (GPrivate* private, gpointer value);
|
||||
};
|
||||
|
||||
GUTILS_C_VAR GThreadFunctions g_thread_functions_for_glib_use;
|
||||
GUTILS_C_VAR gboolean g_thread_use_default_impl;
|
||||
GUTILS_C_VAR gboolean g_thread_supported;
|
||||
|
||||
/* initializes the mutex/cond/private implementation for glib, might
|
||||
* only be called once, and must not be called directly or indirectly
|
||||
* from another glib-function, e.g. as a callback. */
|
||||
void g_thread_init(GThreadFunctions* init);
|
||||
|
||||
/* Internal functions for fallback static mutex implementation
|
||||
* Please don't use it directly
|
||||
*/
|
||||
GMutex* g_static_mutex_get_mutex_impl(GMutex** mutex);
|
||||
|
||||
#define G_USE_THREAD_FUNC_UNCOND(name,arg) \
|
||||
(*g_thread_functions_for_glib_use.name)arg
|
||||
#define G_USE_THREAD_FUNC(name,fail,arg) \
|
||||
(g_thread_supported ? G_USE_THREAD_FUNC_UNCOND(name,arg) : (fail))
|
||||
|
||||
/* keep in mind, all those mutexes and static mutexes are not
|
||||
* recursive in general, don't rely on that */
|
||||
#define g_mutex_new() G_USE_THREAD_FUNC_UNCOND(mutex_new,())
|
||||
#define g_mutex_lock(mutex) G_USE_THREAD_FUNC(mutex_lock,(void)0,(mutex))
|
||||
#define g_mutex_trylock(mutex) G_USE_THREAD_FUNC(mutex_trylock,TRUE,(mutex))
|
||||
#define g_mutex_unlock(mutex) G_USE_THREAD_FUNC(mutex_unlock,(void)0,(mutex))
|
||||
#define g_mutex_free(mutex) G_USE_THREAD_FUNC(mutex_free,(void)0,(mutex))
|
||||
#define g_cond_new() G_USE_THREAD_FUNC_UNCOND(cond_new,())
|
||||
#define g_cond_signal(cond) G_USE_THREAD_FUNC(cond_signal,(void)0,(cond))
|
||||
#define g_cond_broadcast(cond) G_USE_THREAD_FUNC(cond_broadcast,(void)0,(cond))
|
||||
#define g_cond_wait(cond,mutex) G_USE_THREAD_FUNC(cond_wait,(void)0,(cond,mutex))
|
||||
#define g_cond_timed_wait(cond,mutex,abs_time) \
|
||||
G_USE_THREAD_FUNC(cond_timed_wait,TRUE,(cond,mutex,abs_time))
|
||||
#define g_cond_free(cond) G_USE_THREAD_FUNC(cond_free,(void)0,(cond))
|
||||
|
||||
#define g_private_new(destructor) \
|
||||
G_USE_THREAD_FUNC_UNCOND(private_new,(destructor))
|
||||
#define g_private_get(private) \
|
||||
G_USE_THREAD_FUNC(private_get,((gpointer)private),(private))
|
||||
#define g_private_set(private,value) \
|
||||
G_USE_THREAD_FUNC(private_set,(void)(private=(GPrivate *)(value)), \
|
||||
(private,value))
|
||||
|
||||
/* GStaticMutex'es can be statically initialized with the value
|
||||
* G_STATIC_MUTEX_INIT, and then they can directly be used, that is
|
||||
* much easier, than having to explicitly allocate the mutex before
|
||||
* use */
|
||||
#define g_static_mutex_lock(mutex) \
|
||||
g_mutex_lock( g_static_mutex_get_mutex(mutex) )
|
||||
#define g_static_mutex_trylock(mutex) \
|
||||
g_mutex_trylock( g_static_mutex_get_mutex(mutex) )
|
||||
#define g_static_mutex_unlock(mutex) \
|
||||
g_mutex_unlock( g_static_mutex_get_mutex(mutex) )
|
||||
|
||||
struct _GStaticPrivate
|
||||
{
|
||||
guint index;
|
||||
};
|
||||
|
||||
#define G_STATIC_PRIVATE_INIT { 0 }
|
||||
|
||||
gpointer g_static_private_get (GStaticPrivate* private);
|
||||
void g_static_private_set (GStaticPrivate *private,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
/* these are some convenience macros, for using StaticMutex'es, you
|
||||
* define them by G_LOCK_DEFINE(name), where name could for example be the
|
||||
* name of the protected varibale, and you (un)lock them with
|
||||
* g_(un)lock(name) */
|
||||
#define g_lock_name(name) (name ## _lock)
|
||||
#define G_LOCK_DEFINE(name) GStaticMutex g_lock_name(name)=G_STATIC_MUTEX_INIT
|
||||
|
||||
#ifdef G_DEBUG_LOCKS
|
||||
#define g_lock(name) G_STMT_START{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_MESSAGE, \
|
||||
"file %s: line %d (%s): locking: %s ", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#name); \
|
||||
g_static_mutex_lock(g_lock_name(name)); \
|
||||
}G_STMT_END
|
||||
#define g_unlock(name) G_STMT_START{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_MESSAGE, \
|
||||
"file %s: line %d (%s): unlocking: %s ", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#name); \
|
||||
g_static_mutex_unlock(g_lock_name(name)); \
|
||||
}G_STMT_END
|
||||
#define g_trylock(name) G_STMT_START{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_MESSAGE, \
|
||||
"file %s: line %d (%s): try locking: %s ", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#name); \
|
||||
}G_STMT_END, g_static_mutex_trylock(g_lock_name(name))
|
||||
#else /* !G_DEBUG_LOCKS */
|
||||
#define g_lock(name) g_static_mutex_lock(g_lock_name(name))
|
||||
#define g_unlock(name) g_static_mutex_unlock(g_lock_name(name))
|
||||
#define g_trylock(name) g_static_mutex_trylock(g_lock_name(name))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# build . first, then SUBDIRS
|
||||
SUBDIRS = gmodule docs
|
||||
SUBDIRS = gmodule gthread docs
|
||||
all-recursive-am: all-am
|
||||
# alpha `automake' supports this better
|
||||
#SUBDIRS = . gmodule docs
|
||||
@ -50,7 +50,8 @@ libglib_la_SOURCES = \
|
||||
gstring.c \
|
||||
gstrfuncs.c \
|
||||
gscanner.c \
|
||||
gutils.c
|
||||
gutils.c \
|
||||
gmutex.c
|
||||
|
||||
include_HEADERS = \
|
||||
glib.h
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glib.h"
|
||||
|
||||
@ -40,9 +45,8 @@ static gint g_nearest_pow (gint num);
|
||||
static void g_array_maybe_expand (GRealArray *array,
|
||||
gint len);
|
||||
|
||||
|
||||
static GMemChunk *array_mem_chunk = NULL;
|
||||
|
||||
static G_LOCK_DEFINE(array_mem_chunk);
|
||||
|
||||
GArray*
|
||||
g_array_new (gboolean zero_terminated,
|
||||
@ -51,12 +55,14 @@ g_array_new (gboolean zero_terminated,
|
||||
{
|
||||
GRealArray *array;
|
||||
|
||||
g_lock (array_mem_chunk);
|
||||
if (!array_mem_chunk)
|
||||
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||
sizeof (GRealArray),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
array = g_chunk_new (GRealArray, array_mem_chunk);
|
||||
g_unlock (array_mem_chunk);
|
||||
|
||||
array->data = NULL;
|
||||
array->len = 0;
|
||||
@ -75,7 +81,9 @@ g_array_free (GArray *array,
|
||||
if (free_segment)
|
||||
g_free (array->data);
|
||||
|
||||
g_lock (array_mem_chunk);
|
||||
g_mem_chunk_free (array_mem_chunk, array);
|
||||
g_unlock (array_mem_chunk);
|
||||
}
|
||||
|
||||
GArray*
|
||||
@ -241,9 +249,8 @@ struct _GRealPtrArray
|
||||
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||
gint len);
|
||||
|
||||
|
||||
static GMemChunk *ptr_array_mem_chunk = NULL;
|
||||
|
||||
static G_LOCK_DEFINE(ptr_array_mem_chunk);
|
||||
|
||||
|
||||
GPtrArray*
|
||||
@ -251,12 +258,14 @@ g_ptr_array_new (void)
|
||||
{
|
||||
GRealPtrArray *array;
|
||||
|
||||
g_lock (ptr_array_mem_chunk);
|
||||
if (!ptr_array_mem_chunk)
|
||||
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||
sizeof (GRealPtrArray),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
||||
g_unlock (ptr_array_mem_chunk);
|
||||
|
||||
array->pdata = NULL;
|
||||
array->len = 0;
|
||||
@ -274,7 +283,9 @@ g_ptr_array_free (GPtrArray *array,
|
||||
if (free_segment)
|
||||
g_free (array->pdata);
|
||||
|
||||
g_lock (ptr_array_mem_chunk);
|
||||
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
||||
g_unlock (ptr_array_mem_chunk);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -17,6 +17,11 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||
* then
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -56,7 +61,7 @@ static void g_cache_node_destroy (GCacheNode *node);
|
||||
|
||||
|
||||
static GMemChunk *node_mem_chunk = NULL;
|
||||
|
||||
static G_LOCK_DEFINE(node_mem_chunk);
|
||||
|
||||
GCache*
|
||||
g_cache_new (GCacheNewFunc value_new_func,
|
||||
@ -193,11 +198,13 @@ g_cache_node_new (gpointer value)
|
||||
{
|
||||
GCacheNode *node;
|
||||
|
||||
g_lock (node_mem_chunk);
|
||||
if (!node_mem_chunk)
|
||||
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
node = g_chunk_new (GCacheNode, node_mem_chunk);
|
||||
g_unlock (node_mem_chunk);
|
||||
|
||||
node->value = value;
|
||||
node->ref_count = 1;
|
||||
@ -208,5 +215,7 @@ g_cache_node_new (gpointer value)
|
||||
static void
|
||||
g_cache_node_destroy (GCacheNode *node)
|
||||
{
|
||||
g_lock (node_mem_chunk);
|
||||
g_mem_chunk_free (node_mem_chunk, node);
|
||||
g_unlock (node_mem_chunk);
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <string.h>
|
||||
|
||||
|
@ -18,6 +18,12 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe ; FIXME: might still freeze, watch out, not thoroughly
|
||||
* looked at yet.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "glib.h"
|
||||
|
||||
@ -61,18 +67,24 @@ static inline GQuark g_quark_new (gchar *string);
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
static G_LOCK_DEFINE(g_dataset_global);
|
||||
static GHashTable *g_dataset_location_ht = NULL;
|
||||
static GDataset *g_dataset_cached = NULL;
|
||||
static GDataset *g_dataset_cached = NULL; /* should this be
|
||||
threadspecific? */
|
||||
static GMemChunk *g_dataset_mem_chunk = NULL;
|
||||
static GMemChunk *g_data_mem_chunk = NULL;
|
||||
static GData *g_data_cache = NULL;
|
||||
static guint g_data_cache_length = 0;
|
||||
|
||||
static G_LOCK_DEFINE(g_quark_global);
|
||||
static GHashTable *g_quark_ht = NULL;
|
||||
static gchar **g_quarks = NULL;
|
||||
static GQuark g_quark_seq_id = 0;
|
||||
|
||||
|
||||
/* --- functions --- */
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static inline void
|
||||
g_datalist_clear_i (GData **datalist)
|
||||
{
|
||||
@ -109,13 +121,16 @@ g_datalist_clear (GData **datalist)
|
||||
{
|
||||
g_return_if_fail (datalist != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (!g_dataset_location_ht)
|
||||
g_data_initialize ();
|
||||
|
||||
while (*datalist)
|
||||
g_datalist_clear_i (datalist);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static inline GDataset*
|
||||
g_dataset_lookup (gconstpointer dataset_location)
|
||||
{
|
||||
@ -131,6 +146,7 @@ g_dataset_lookup (gconstpointer dataset_location)
|
||||
return dataset;
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static void
|
||||
g_dataset_destroy_internal (GDataset *dataset)
|
||||
{
|
||||
@ -158,6 +174,7 @@ g_dataset_destroy (gconstpointer dataset_location)
|
||||
{
|
||||
g_return_if_fail (dataset_location != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (g_dataset_location_ht)
|
||||
{
|
||||
register GDataset *dataset;
|
||||
@ -166,8 +183,10 @@ g_dataset_destroy (gconstpointer dataset_location)
|
||||
if (dataset)
|
||||
g_dataset_destroy_internal (dataset);
|
||||
}
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static inline void
|
||||
g_data_set_internal (GData **datalist,
|
||||
GQuark key_id,
|
||||
@ -293,9 +312,10 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
|
||||
return;
|
||||
}
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (!g_dataset_location_ht)
|
||||
g_data_initialize ();
|
||||
|
||||
|
||||
dataset = g_dataset_lookup (dataset_location);
|
||||
if (!dataset)
|
||||
{
|
||||
@ -308,6 +328,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
|
||||
}
|
||||
|
||||
g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
void
|
||||
@ -327,10 +348,12 @@ g_datalist_id_set_data_full (GData **datalist,
|
||||
return;
|
||||
}
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (!g_dataset_location_ht)
|
||||
g_data_initialize ();
|
||||
|
||||
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
void
|
||||
@ -339,6 +362,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
||||
{
|
||||
g_return_if_fail (dataset_location != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (key_id && g_dataset_location_ht)
|
||||
{
|
||||
GDataset *dataset;
|
||||
@ -346,7 +370,8 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
||||
dataset = g_dataset_lookup (dataset_location);
|
||||
if (dataset)
|
||||
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
|
||||
}
|
||||
}
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
void
|
||||
@ -355,8 +380,10 @@ g_datalist_id_remove_no_notify (GData **datalist,
|
||||
{
|
||||
g_return_if_fail (datalist != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (key_id && g_dataset_location_ht)
|
||||
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
|
||||
gpointer
|
||||
@ -365,6 +392,7 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
||||
{
|
||||
g_return_val_if_fail (dataset_location != NULL, NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (key_id && g_dataset_location_ht)
|
||||
{
|
||||
register GDataset *dataset;
|
||||
@ -376,10 +404,14 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
||||
|
||||
for (list = dataset->datalist; list; list = list->next)
|
||||
if (list->id == key_id)
|
||||
return list->data;
|
||||
{
|
||||
g_unlock (g_dataset_global);
|
||||
return list->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_unlock (g_dataset_global);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -411,17 +443,23 @@ g_dataset_foreach (gconstpointer dataset_location,
|
||||
g_return_if_fail (dataset_location != NULL);
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
g_lock (g_dataset_global);
|
||||
if (g_dataset_location_ht)
|
||||
{
|
||||
dataset = g_dataset_lookup (dataset_location);
|
||||
g_unlock (g_dataset_global);
|
||||
if (dataset)
|
||||
{
|
||||
register GData *list;
|
||||
|
||||
for (list = dataset->datalist; list; list = list->next)
|
||||
func (list->id, list->data, user_data);
|
||||
func (list->id, list->data, user_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_unlock (g_dataset_global);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -446,6 +484,7 @@ g_datalist_init (GData **datalist)
|
||||
*datalist = NULL;
|
||||
}
|
||||
|
||||
/* HOLDS: g_dataset_global_lock */
|
||||
static void
|
||||
g_data_initialize (void)
|
||||
{
|
||||
@ -468,12 +507,15 @@ g_data_initialize (void)
|
||||
GQuark
|
||||
g_quark_try_string (const gchar *string)
|
||||
{
|
||||
GQuark quark = 0;
|
||||
g_return_val_if_fail (string != NULL, 0);
|
||||
|
||||
g_lock (g_quark_global);
|
||||
if (g_quark_ht)
|
||||
return (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||
else
|
||||
return 0;
|
||||
quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
GQuark
|
||||
@ -483,6 +525,7 @@ g_quark_from_string (const gchar *string)
|
||||
|
||||
g_return_val_if_fail (string != NULL, 0);
|
||||
|
||||
g_lock (g_quark_global);
|
||||
if (g_quark_ht)
|
||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||
else
|
||||
@ -493,6 +536,7 @@ g_quark_from_string (const gchar *string)
|
||||
|
||||
if (!quark)
|
||||
quark = g_quark_new (g_strdup (string));
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return quark;
|
||||
}
|
||||
@ -504,6 +548,7 @@ g_quark_from_static_string (const gchar *string)
|
||||
|
||||
g_return_val_if_fail (string != NULL, 0);
|
||||
|
||||
g_lock (g_quark_global);
|
||||
if (g_quark_ht)
|
||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||
else
|
||||
@ -514,19 +559,24 @@ g_quark_from_static_string (const gchar *string)
|
||||
|
||||
if (!quark)
|
||||
quark = g_quark_new ((gchar*) string);
|
||||
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
gchar*
|
||||
g_quark_to_string (GQuark quark)
|
||||
{
|
||||
gchar* result = NULL;
|
||||
g_lock (g_quark_global);
|
||||
if (quark > 0 && quark <= g_quark_seq_id)
|
||||
return g_quarks[quark - 1];
|
||||
else
|
||||
return NULL;
|
||||
result = g_quarks[quark - 1];
|
||||
g_unlock (g_quark_global);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* HOLDS: g_quark_global_lock */
|
||||
static inline GQuark
|
||||
g_quark_new (gchar *string)
|
||||
{
|
||||
|
24
glib/gdate.c
24
glib/gdate.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
#include <time.h>
|
||||
@ -383,6 +388,8 @@ g_date_clear (GDate *d, guint ndates)
|
||||
memset (d, 0x0, ndates*sizeof (GDate));
|
||||
}
|
||||
|
||||
static G_LOCK_DEFINE(g_date_global);
|
||||
|
||||
/* These are for the parser, output to the user should use *
|
||||
* g_date_strftime () - this creates more never-freed memory to annoy
|
||||
* all those memory debugger users. :-)
|
||||
@ -429,6 +436,7 @@ typedef struct _GDateParseTokens GDateParseTokens;
|
||||
|
||||
#define NUM_LEN 10
|
||||
|
||||
/* HOLDS: g_date_global_lock */
|
||||
static void
|
||||
g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
||||
{
|
||||
@ -488,7 +496,7 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
||||
if (found != NULL)
|
||||
{
|
||||
pt->month = i;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,12 +510,13 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* HOLDS: g_date_global_lock */
|
||||
static void
|
||||
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
|
||||
{
|
||||
@ -641,6 +650,8 @@ g_date_set_parse (GDate *d,
|
||||
/* set invalid */
|
||||
g_date_clear (d, 1);
|
||||
|
||||
g_lock (g_date_global);
|
||||
|
||||
g_date_prepare_to_parse (str, &pt);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -649,7 +660,11 @@ g_date_set_parse (GDate *d,
|
||||
#endif
|
||||
|
||||
|
||||
if (pt.num_ints == 4) return; /* presumably a typo; bail out. */
|
||||
if (pt.num_ints == 4)
|
||||
{
|
||||
g_unlock (g_date_global);
|
||||
return; /* presumably a typo; bail out. */
|
||||
}
|
||||
|
||||
if (pt.num_ints > 1)
|
||||
{
|
||||
@ -765,6 +780,7 @@ g_date_set_parse (GDate *d,
|
||||
else
|
||||
g_message ("Rejected DMY %u %u %u", day, m, y);
|
||||
#endif
|
||||
g_unlock (g_date_global);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -17,6 +17,11 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||
* then
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
13
glib/ghash.c
13
glib/ghash.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -52,6 +57,8 @@ static void g_hash_node_destroy (GHashNode *hash_node);
|
||||
static void g_hash_nodes_destroy (GHashNode *hash_node);
|
||||
|
||||
|
||||
static G_LOCK_DEFINE(g_hash_global);
|
||||
|
||||
static GMemChunk *node_mem_chunk = NULL;
|
||||
static GHashNode *node_free_list = NULL;
|
||||
|
||||
@ -338,6 +345,7 @@ g_hash_node_new (gpointer key,
|
||||
{
|
||||
GHashNode *hash_node;
|
||||
|
||||
g_lock (g_hash_global);
|
||||
if (node_free_list)
|
||||
{
|
||||
hash_node = node_free_list;
|
||||
@ -352,6 +360,7 @@ g_hash_node_new (gpointer key,
|
||||
|
||||
hash_node = g_chunk_new (GHashNode, node_mem_chunk);
|
||||
}
|
||||
g_unlock (g_hash_global);
|
||||
|
||||
hash_node->key = key;
|
||||
hash_node->value = value;
|
||||
@ -363,8 +372,10 @@ g_hash_node_new (gpointer key,
|
||||
static void
|
||||
g_hash_node_destroy (GHashNode *hash_node)
|
||||
{
|
||||
g_lock (g_hash_global);
|
||||
hash_node->next = node_free_list;
|
||||
node_free_list = hash_node;
|
||||
g_unlock (g_hash_global);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -380,6 +391,8 @@ g_hash_nodes_destroy (GHashNode *hash_node)
|
||||
while (node->next)
|
||||
node = node->next;
|
||||
|
||||
g_lock (g_hash_global);
|
||||
node->next = node_free_list;
|
||||
node_free_list = hash_node;
|
||||
g_unlock (g_hash_global);
|
||||
}
|
||||
|
@ -19,6 +19,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
134
glib/glib.h
134
glib/glib.h
@ -2597,6 +2597,140 @@ gint gwin_closedir (DIR *dir);
|
||||
|
||||
#endif /* NATIVE_WIN32 */
|
||||
|
||||
/* functions for thread support for glib. */
|
||||
|
||||
typedef struct _GMutex GMutex;
|
||||
typedef struct _GCond GCond;
|
||||
typedef struct _GPrivate GPrivate;
|
||||
typedef struct _GStaticPrivate GStaticPrivate;
|
||||
|
||||
typedef struct _GThreadFunctions GThreadFunctions;
|
||||
struct _GThreadFunctions
|
||||
{
|
||||
GMutex* (*mutex_new) (void);
|
||||
void (*mutex_lock) (GMutex* mutex);
|
||||
gboolean (*mutex_trylock) (GMutex* mutex);
|
||||
void (*mutex_unlock) (GMutex* mutex);
|
||||
void (*mutex_free) (GMutex* mutex);
|
||||
GCond* (*cond_new) (void);
|
||||
void (*cond_signal) (GCond* cond);
|
||||
void (*cond_broadcast) (GCond* cond);
|
||||
void (*cond_wait) (GCond* cond, GMutex* mutex);
|
||||
gboolean (*cond_timed_wait) (GCond* cond, GMutex* mutex,
|
||||
GTimeVal *end_time);
|
||||
void (*cond_free) (GCond* cond);
|
||||
GPrivate* (*private_new) (GDestroyNotify destructor);
|
||||
gpointer (*private_get) (GPrivate* private);
|
||||
void (*private_set) (GPrivate* private, gpointer value);
|
||||
};
|
||||
|
||||
GUTILS_C_VAR GThreadFunctions g_thread_functions_for_glib_use;
|
||||
GUTILS_C_VAR gboolean g_thread_use_default_impl;
|
||||
GUTILS_C_VAR gboolean g_thread_supported;
|
||||
|
||||
/* initializes the mutex/cond/private implementation for glib, might
|
||||
* only be called once, and must not be called directly or indirectly
|
||||
* from another glib-function, e.g. as a callback. */
|
||||
void g_thread_init(GThreadFunctions* init);
|
||||
|
||||
/* Internal functions for fallback static mutex implementation
|
||||
* Please don't use it directly
|
||||
*/
|
||||
GMutex* g_static_mutex_get_mutex_impl(GMutex** mutex);
|
||||
|
||||
#define G_USE_THREAD_FUNC_UNCOND(name,arg) \
|
||||
(*g_thread_functions_for_glib_use.name)arg
|
||||
#define G_USE_THREAD_FUNC(name,fail,arg) \
|
||||
(g_thread_supported ? G_USE_THREAD_FUNC_UNCOND(name,arg) : (fail))
|
||||
|
||||
/* keep in mind, all those mutexes and static mutexes are not
|
||||
* recursive in general, don't rely on that */
|
||||
#define g_mutex_new() G_USE_THREAD_FUNC_UNCOND(mutex_new,())
|
||||
#define g_mutex_lock(mutex) G_USE_THREAD_FUNC(mutex_lock,(void)0,(mutex))
|
||||
#define g_mutex_trylock(mutex) G_USE_THREAD_FUNC(mutex_trylock,TRUE,(mutex))
|
||||
#define g_mutex_unlock(mutex) G_USE_THREAD_FUNC(mutex_unlock,(void)0,(mutex))
|
||||
#define g_mutex_free(mutex) G_USE_THREAD_FUNC(mutex_free,(void)0,(mutex))
|
||||
#define g_cond_new() G_USE_THREAD_FUNC_UNCOND(cond_new,())
|
||||
#define g_cond_signal(cond) G_USE_THREAD_FUNC(cond_signal,(void)0,(cond))
|
||||
#define g_cond_broadcast(cond) G_USE_THREAD_FUNC(cond_broadcast,(void)0,(cond))
|
||||
#define g_cond_wait(cond,mutex) G_USE_THREAD_FUNC(cond_wait,(void)0,(cond,mutex))
|
||||
#define g_cond_timed_wait(cond,mutex,abs_time) \
|
||||
G_USE_THREAD_FUNC(cond_timed_wait,TRUE,(cond,mutex,abs_time))
|
||||
#define g_cond_free(cond) G_USE_THREAD_FUNC(cond_free,(void)0,(cond))
|
||||
|
||||
#define g_private_new(destructor) \
|
||||
G_USE_THREAD_FUNC_UNCOND(private_new,(destructor))
|
||||
#define g_private_get(private) \
|
||||
G_USE_THREAD_FUNC(private_get,((gpointer)private),(private))
|
||||
#define g_private_set(private,value) \
|
||||
G_USE_THREAD_FUNC(private_set,(void)(private=(GPrivate *)(value)), \
|
||||
(private,value))
|
||||
|
||||
/* GStaticMutex'es can be statically initialized with the value
|
||||
* G_STATIC_MUTEX_INIT, and then they can directly be used, that is
|
||||
* much easier, than having to explicitly allocate the mutex before
|
||||
* use */
|
||||
#define g_static_mutex_lock(mutex) \
|
||||
g_mutex_lock( g_static_mutex_get_mutex(mutex) )
|
||||
#define g_static_mutex_trylock(mutex) \
|
||||
g_mutex_trylock( g_static_mutex_get_mutex(mutex) )
|
||||
#define g_static_mutex_unlock(mutex) \
|
||||
g_mutex_unlock( g_static_mutex_get_mutex(mutex) )
|
||||
|
||||
struct _GStaticPrivate
|
||||
{
|
||||
guint index;
|
||||
};
|
||||
|
||||
#define G_STATIC_PRIVATE_INIT { 0 }
|
||||
|
||||
gpointer g_static_private_get (GStaticPrivate* private);
|
||||
void g_static_private_set (GStaticPrivate *private,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
/* these are some convenience macros, for using StaticMutex'es, you
|
||||
* define them by G_LOCK_DEFINE(name), where name could for example be the
|
||||
* name of the protected varibale, and you (un)lock them with
|
||||
* g_(un)lock(name) */
|
||||
#define g_lock_name(name) (name ## _lock)
|
||||
#define G_LOCK_DEFINE(name) GStaticMutex g_lock_name(name)=G_STATIC_MUTEX_INIT
|
||||
|
||||
#ifdef G_DEBUG_LOCKS
|
||||
#define g_lock(name) G_STMT_START{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_MESSAGE, \
|
||||
"file %s: line %d (%s): locking: %s ", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#name); \
|
||||
g_static_mutex_lock(g_lock_name(name)); \
|
||||
}G_STMT_END
|
||||
#define g_unlock(name) G_STMT_START{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_MESSAGE, \
|
||||
"file %s: line %d (%s): unlocking: %s ", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#name); \
|
||||
g_static_mutex_unlock(g_lock_name(name)); \
|
||||
}G_STMT_END
|
||||
#define g_trylock(name) G_STMT_START{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_MESSAGE, \
|
||||
"file %s: line %d (%s): try locking: %s ", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#name); \
|
||||
}G_STMT_END, g_static_mutex_trylock(g_lock_name(name))
|
||||
#else /* !G_DEBUG_LOCKS */
|
||||
#define g_lock(name) g_static_mutex_lock(g_lock_name(name))
|
||||
#define g_unlock(name) g_static_mutex_unlock(g_lock_name(name))
|
||||
#define g_trylock(name) g_static_mutex_trylock(g_lock_name(name))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
44
glib/glist.c
44
glib/glist.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -31,9 +36,11 @@ struct _GAllocator /* from gmem.c */
|
||||
};
|
||||
|
||||
static GAllocator *current_allocator = NULL;
|
||||
static G_LOCK_DEFINE(current_allocator);
|
||||
|
||||
void
|
||||
g_list_push_allocator (GAllocator *allocator)
|
||||
/* HOLDS: current_allocator_lock */
|
||||
static void
|
||||
g_list_validate_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_return_if_fail (allocator != NULL);
|
||||
g_return_if_fail (allocator->is_unused == TRUE);
|
||||
@ -58,13 +65,22 @@ g_list_push_allocator (GAllocator *allocator)
|
||||
}
|
||||
|
||||
allocator->is_unused = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_list_push_allocator(GAllocator *allocator)
|
||||
{
|
||||
g_list_validate_allocator ( allocator );
|
||||
g_lock (current_allocator);
|
||||
allocator->last = current_allocator;
|
||||
current_allocator = allocator;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_list_pop_allocator (void)
|
||||
{
|
||||
g_lock (current_allocator);
|
||||
if (current_allocator)
|
||||
{
|
||||
GAllocator *allocator;
|
||||
@ -74,6 +90,7 @@ g_list_pop_allocator (void)
|
||||
allocator->last = NULL;
|
||||
allocator->is_unused = TRUE;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
GList*
|
||||
@ -81,9 +98,15 @@ g_list_alloc (void)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_lock (current_allocator);
|
||||
if (!current_allocator)
|
||||
g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
|
||||
|
||||
{
|
||||
GAllocator *allocator = g_allocator_new ("GLib default GList allocator",
|
||||
1024);
|
||||
g_list_validate_allocator (allocator);
|
||||
allocator->last = NULL;
|
||||
current_allocator = allocator;
|
||||
}
|
||||
if (!current_allocator->free_lists)
|
||||
{
|
||||
list = g_chunk_new (GList, current_allocator->mem_chunk);
|
||||
@ -103,6 +126,7 @@ g_list_alloc (void)
|
||||
current_allocator->free_lists = list->next;
|
||||
}
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
list->next = NULL;
|
||||
list->prev = NULL;
|
||||
|
||||
@ -112,23 +136,31 @@ g_list_alloc (void)
|
||||
void
|
||||
g_list_free (GList *list)
|
||||
{
|
||||
#if 0
|
||||
if (list)
|
||||
{
|
||||
list->data = list->next;
|
||||
list->data = list->next;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
g_list_free_1 (GList *list)
|
||||
{
|
||||
#if 0
|
||||
if (list)
|
||||
{
|
||||
list->data = NULL;
|
||||
list->data = NULL;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
GList*
|
||||
|
158
glib/gmain.c
158
glib/gmain.c
@ -20,9 +20,14 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "config.h"
|
||||
|
||||
/* Types */
|
||||
@ -65,9 +70,12 @@ struct _GPollRec {
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
static void g_main_poll (gint timeout,
|
||||
gboolean use_priority,
|
||||
gint priority);
|
||||
static void g_main_poll (gint timeout,
|
||||
gboolean use_priority,
|
||||
gint priority);
|
||||
static void g_main_poll_add_unlocked (gint priority,
|
||||
GPollFD *fd);
|
||||
|
||||
static gboolean g_timeout_prepare (gpointer source_data,
|
||||
GTimeVal *current_time,
|
||||
gint *timeout);
|
||||
@ -90,6 +98,11 @@ static gboolean g_idle_dispatch (gpointer source_data,
|
||||
static GSList *pending_dispatches = NULL;
|
||||
static GHookList source_list = { 0 };
|
||||
|
||||
/* The following lock is used for both the list of sources
|
||||
* and the list of poll records
|
||||
*/
|
||||
static G_LOCK_DEFINE (main_loop);
|
||||
|
||||
static GSourceFuncs timeout_funcs = {
|
||||
g_timeout_prepare,
|
||||
g_timeout_check,
|
||||
@ -104,6 +117,17 @@ static GSourceFuncs idle_funcs = {
|
||||
(GDestroyNotify)g_free
|
||||
};
|
||||
|
||||
static GPollRec *poll_records = NULL;
|
||||
static GPollRec *poll_free_list = NULL;
|
||||
static GMemChunk *poll_chunk;
|
||||
static guint n_poll_records = 0;
|
||||
|
||||
/* this pipe is used to wake up the main loop when a source is added.
|
||||
*/
|
||||
static gint wake_up_pipe[2] = { -1, -1 };
|
||||
static GPollFD wake_up_rec;
|
||||
static gboolean poll_waiting = FALSE;
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
static GPollFunc poll_func = (GPollFunc)poll;
|
||||
#else
|
||||
@ -205,8 +229,11 @@ g_source_add (gint priority,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
guint return_val;
|
||||
GSource *source;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
if (!source_list.is_setup)
|
||||
g_hook_list_init (&source_list, sizeof(GSource));
|
||||
|
||||
@ -224,31 +251,55 @@ g_source_add (gint priority,
|
||||
if (can_recurse)
|
||||
source->hook.flags |= G_SOURCE_CAN_RECURSE;
|
||||
|
||||
return source->hook.hook_id;
|
||||
return_val = source->hook.hook_id;
|
||||
|
||||
/* Now wake up the main loop if it is waiting in the poll() */
|
||||
|
||||
if (poll_waiting)
|
||||
{
|
||||
poll_waiting = FALSE;
|
||||
write (wake_up_pipe[1], "A", 1);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void
|
||||
g_source_remove (guint tag)
|
||||
{
|
||||
GHook *hook = g_hook_get (&source_list, tag);
|
||||
GHook *hook;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
hook = g_hook_get (&source_list, tag);
|
||||
if (hook)
|
||||
{
|
||||
GSource *source = (GSource *)hook;
|
||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||
g_hook_destroy_link (&source_list, hook);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void
|
||||
g_source_remove_by_user_data (gpointer user_data)
|
||||
{
|
||||
GHook *hook = g_hook_find_data (&source_list, TRUE, user_data);
|
||||
GHook *hook;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
hook = g_hook_find_data (&source_list, TRUE, user_data);
|
||||
if (hook)
|
||||
{
|
||||
GSource *source = (GSource *)hook;
|
||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||
g_hook_destroy_link (&source_list, hook);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -262,7 +313,11 @@ g_source_find_source_data (GHook *hook,
|
||||
void
|
||||
g_source_remove_by_source_data (gpointer source_data)
|
||||
{
|
||||
GHook *hook = g_hook_find (&source_list, TRUE,
|
||||
GHook *hook;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
hook = g_hook_find (&source_list, TRUE,
|
||||
g_source_find_source_data, source_data);
|
||||
if (hook)
|
||||
{
|
||||
@ -270,6 +325,8 @@ g_source_remove_by_source_data (gpointer source_data)
|
||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||
g_hook_destroy_link (&source_list, hook);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void g_get_current_time (GTimeVal *result)
|
||||
@ -279,6 +336,7 @@ void g_get_current_time (GTimeVal *result)
|
||||
|
||||
/* Running the main loop */
|
||||
|
||||
/* HOLDS: main_loop_lock */
|
||||
static void
|
||||
g_main_dispatch (GTimeVal *current_time)
|
||||
{
|
||||
@ -294,10 +352,20 @@ g_main_dispatch (GTimeVal *current_time)
|
||||
|
||||
if (G_HOOK_IS_VALID (source))
|
||||
{
|
||||
gboolean (*dispatch) (gpointer, GTimeVal *, gpointer);
|
||||
gpointer hook_data = source->hook.data;
|
||||
gpointer source_data = source->source_data;
|
||||
|
||||
dispatch = ((GSourceFuncs *)source->hook.func)->dispatch;
|
||||
|
||||
source->hook.flags |= G_HOOK_FLAG_IN_CALL;
|
||||
need_destroy = !((GSourceFuncs *)source->hook.func)->dispatch (source->source_data,
|
||||
current_time,
|
||||
source->hook.data);
|
||||
|
||||
g_unlock (main_loop);
|
||||
need_destroy = ! dispatch(source_data,
|
||||
current_time,
|
||||
hook_data);
|
||||
g_lock (main_loop);
|
||||
|
||||
source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
|
||||
|
||||
if (need_destroy)
|
||||
@ -320,10 +388,13 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
gint nready = 0;
|
||||
gint current_priority = 0;
|
||||
gint timeout;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
g_return_val_if_fail (!block || dispatch, FALSE);
|
||||
|
||||
g_get_current_time (¤t_time);
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
/* If recursing, finish up current dispatch, before starting over */
|
||||
if (pending_dispatches)
|
||||
@ -331,6 +402,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
if (dispatch)
|
||||
g_main_dispatch (¤t_time);
|
||||
|
||||
g_unlock (main_loop);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -362,6 +434,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
if (!dispatch)
|
||||
{
|
||||
g_hook_unref (&source_list, hook);
|
||||
g_unlock (main_loop);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@ -426,6 +499,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
else
|
||||
{
|
||||
g_hook_unref (&source_list, hook);
|
||||
g_unlock (main_loop);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -442,10 +516,12 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
{
|
||||
pending_dispatches = g_slist_reverse (pending_dispatches);
|
||||
g_main_dispatch (¤t_time);
|
||||
return TRUE;
|
||||
retval = TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
g_unlock (main_loop);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* See if any events are pending
|
||||
@ -494,11 +570,7 @@ g_main_destroy (GMainLoop *loop)
|
||||
g_free (loop);
|
||||
}
|
||||
|
||||
static GPollRec *poll_records = NULL;
|
||||
static GPollRec *poll_free_list = NULL;
|
||||
static GMemChunk *poll_chunk;
|
||||
static guint n_poll_records = 0;
|
||||
|
||||
/* HOLDS: main_loop_lock */
|
||||
static void
|
||||
g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
{
|
||||
@ -508,6 +580,17 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
gint i;
|
||||
gint npoll;
|
||||
|
||||
if (wake_up_pipe[0] < 0)
|
||||
{
|
||||
if (pipe (wake_up_pipe) < 0)
|
||||
g_error ("Cannot create pipe main loop wake-up: %s\n",
|
||||
g_strerror(errno));
|
||||
|
||||
wake_up_rec.fd = wake_up_pipe[0];
|
||||
wake_up_rec.events = G_IO_IN;
|
||||
g_main_poll_add_unlocked (0, &wake_up_rec);
|
||||
}
|
||||
|
||||
pollrec = poll_records;
|
||||
i = 0;
|
||||
while (pollrec && (!use_priority || priority >= pollrec->priority))
|
||||
@ -520,8 +603,20 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
i++;
|
||||
}
|
||||
|
||||
poll_waiting = TRUE;
|
||||
|
||||
g_unlock (main_loop);
|
||||
npoll = i;
|
||||
(*poll_func) (fd_array, npoll, timeout);
|
||||
g_lock (main_loop);
|
||||
|
||||
if (!poll_waiting)
|
||||
{
|
||||
gchar c;
|
||||
read (wake_up_pipe[0], &c, 1);
|
||||
}
|
||||
else
|
||||
poll_waiting = FALSE;
|
||||
|
||||
pollrec = poll_records;
|
||||
i = 0;
|
||||
@ -538,13 +633,29 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
void
|
||||
g_main_poll_add (gint priority,
|
||||
GPollFD *fd)
|
||||
{
|
||||
g_lock (main_loop);
|
||||
g_main_poll_add_unlocked (priority, fd);
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
g_main_poll_add_unlocked (gint priority,
|
||||
GPollFD *fd)
|
||||
{
|
||||
GPollRec *lastrec, *pollrec, *newrec;
|
||||
|
||||
if (!poll_chunk)
|
||||
poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
|
||||
|
||||
newrec = g_chunk_new (GPollRec, poll_chunk);
|
||||
if (poll_free_list)
|
||||
{
|
||||
newrec = poll_free_list;
|
||||
poll_free_list = newrec->next;
|
||||
}
|
||||
else
|
||||
newrec = g_chunk_new (GPollRec, poll_chunk);
|
||||
|
||||
newrec->fd = fd;
|
||||
newrec->priority = priority;
|
||||
|
||||
@ -564,6 +675,8 @@ g_main_poll_add (gint priority,
|
||||
newrec->next = pollrec;
|
||||
|
||||
n_poll_records++;
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void
|
||||
@ -571,6 +684,8 @@ g_main_poll_remove (GPollFD *fd)
|
||||
{
|
||||
GPollRec *pollrec, *lastrec;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
lastrec = NULL;
|
||||
pollrec = poll_records;
|
||||
|
||||
@ -585,12 +700,15 @@ g_main_poll_remove (GPollFD *fd)
|
||||
|
||||
pollrec->next = poll_free_list;
|
||||
poll_free_list = pollrec;
|
||||
|
||||
n_poll_records--;
|
||||
break;
|
||||
}
|
||||
lastrec = pollrec;
|
||||
pollrec = pollrec->next;
|
||||
}
|
||||
|
||||
n_poll_records--;
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void
|
||||
|
89
glib/gmem.c
89
glib/gmem.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -48,8 +52,12 @@
|
||||
*/
|
||||
|
||||
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
|
||||
#define ENTER_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk++
|
||||
#define LEAVE_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk--
|
||||
#define ENTER_MEM_CHUNK_ROUTINE() \
|
||||
g_static_set (allocating_for_mem_chunk, \
|
||||
g_static_get (allocating_for_mem_chunk) + 1)
|
||||
#define ENTER_MEM_CHUNK_ROUTINE() \
|
||||
g_static_set (allocating_for_mem_chunk, \
|
||||
g_static_get (allocating_for_mem_chunk) - 1)
|
||||
#else
|
||||
#define ENTER_MEM_CHUNK_ROUTINE()
|
||||
#define LEAVE_MEM_CHUNK_ROUTINE()
|
||||
@ -117,13 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
|
||||
gchar *addr);
|
||||
|
||||
|
||||
/* here we can't use StaticMutexes, as they depend upon a working
|
||||
* g_malloc, the same holds true for StaticPrivate */
|
||||
static GMutex* mem_chunks_lock = NULL;
|
||||
static GRealMemChunk *mem_chunks = NULL;
|
||||
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
static GMutex* mem_profile_lock;
|
||||
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
|
||||
static gulong allocated_mem = 0;
|
||||
static gulong freed_mem = 0;
|
||||
static gint allocating_for_mem_chunk = 0;
|
||||
static GPrivate* allocating_for_mem_chunk = NULL;
|
||||
#define IS_IN_MEM_CHUNK_ROUTINE() \
|
||||
GPOINTER_TO_UINT (g_static_get (allocating_for_mem_chunk))
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
|
||||
|
||||
@ -174,8 +188,9 @@ g_malloc (gulong size)
|
||||
*t = size;
|
||||
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile_lock);
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
if(!allocating_for_mem_chunk) {
|
||||
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||
# endif
|
||||
if (size <= MEM_PROFILE_TABLE_SIZE - 1)
|
||||
allocations[size-1] += 1;
|
||||
@ -185,6 +200,7 @@ g_malloc (gulong size)
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
}
|
||||
# endif
|
||||
g_mutex_unlock (mem_profile_lock);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
|
||||
@ -237,8 +253,9 @@ g_malloc0 (gulong size)
|
||||
*t = size;
|
||||
|
||||
# ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile_lock);
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
if(!allocating_for_mem_chunk) {
|
||||
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||
# endif
|
||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||
allocations[size-1] += 1;
|
||||
@ -248,8 +265,9 @@ g_malloc0 (gulong size)
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
}
|
||||
# endif
|
||||
g_mutex_unlock (mem_profile_lock);
|
||||
# endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
|
||||
|
||||
return p;
|
||||
@ -286,7 +304,9 @@ g_realloc (gpointer mem,
|
||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile);
|
||||
freed_mem += *t;
|
||||
g_mutex_unlock (mem_profile);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
mem = t;
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
@ -321,8 +341,9 @@ g_realloc (gpointer mem,
|
||||
*t = size;
|
||||
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile_lock);
|
||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
if(!allocating_for_mem_chunk) {
|
||||
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||
#endif
|
||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||
allocations[size-1] += 1;
|
||||
@ -332,6 +353,7 @@ g_realloc (gpointer mem,
|
||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
}
|
||||
#endif
|
||||
g_mutex_unlock (mem_profile_lock);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
|
||||
@ -352,8 +374,10 @@ g_free (gpointer mem)
|
||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||
size = *t;
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile);
|
||||
freed_mem += size;
|
||||
g_mutex_unlock (mem_profile);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
mem = t;
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
@ -380,19 +404,29 @@ g_mem_profile (void)
|
||||
{
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
gint i;
|
||||
|
||||
gulong local_allocations[MEM_PROFILE_TABLE_SIZE];
|
||||
gulong local_allocated_mem;
|
||||
gulong local_freed_mem;
|
||||
|
||||
g_mutex_lock (mem_profile);
|
||||
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
|
||||
if (allocations[i] > 0)
|
||||
local_allocations[i] = allocations[i];
|
||||
local_allocated_mem = allocated_mem;
|
||||
local_freed_mem = freed_mem;
|
||||
g_mutex_unlock (mem_profile);
|
||||
|
||||
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
|
||||
if (local_allocations[i] > 0)
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
|
||||
"%lu allocations of %d bytes\n", allocations[i], i + 1);
|
||||
"%lu allocations of %d bytes\n", local_allocations[i], i + 1);
|
||||
|
||||
if (allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0)
|
||||
if (local_allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0)
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
|
||||
"%lu allocations of greater than %d bytes\n",
|
||||
allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", allocated_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", freed_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", allocated_mem - freed_mem);
|
||||
local_allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", local_allocated_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", local_freed_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", local_allocated_mem - local_freed_mem);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
}
|
||||
|
||||
@ -460,11 +494,13 @@ g_mem_chunk_new (gchar *name,
|
||||
mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
|
||||
*/
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk->next = mem_chunks;
|
||||
mem_chunk->prev = NULL;
|
||||
if (mem_chunks)
|
||||
mem_chunks->prev = mem_chunk;
|
||||
mem_chunks = mem_chunk;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
LEAVE_MEM_CHUNK_ROUTINE();
|
||||
|
||||
@ -497,8 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
|
||||
if (rmem_chunk->prev)
|
||||
rmem_chunk->prev->next = rmem_chunk->next;
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
if (rmem_chunk == mem_chunks)
|
||||
mem_chunks = mem_chunks->next;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
if (rmem_chunk->type == G_ALLOC_AND_FREE)
|
||||
g_tree_destroy (rmem_chunk->mem_tree);
|
||||
@ -826,21 +864,26 @@ g_mem_chunk_info (void)
|
||||
gint count;
|
||||
|
||||
count = 0;
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk = mem_chunks;
|
||||
while (mem_chunk)
|
||||
{
|
||||
count += 1;
|
||||
mem_chunk = mem_chunk->next;
|
||||
}
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count);
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk = mem_chunks;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
while (mem_chunk)
|
||||
{
|
||||
g_mem_chunk_print ((GMemChunk*) mem_chunk);
|
||||
mem_chunk = mem_chunk->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -848,7 +891,9 @@ g_blow_chunks (void)
|
||||
{
|
||||
GRealMemChunk *mem_chunk;
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk = mem_chunks;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
while (mem_chunk)
|
||||
{
|
||||
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
|
||||
@ -940,3 +985,13 @@ g_allocator_free (GAllocator *allocator)
|
||||
|
||||
g_free (allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_mem_init (void)
|
||||
{
|
||||
mem_chunks_lock = g_mutex_new();
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
mem_profile_lock = g_mutex_new();
|
||||
allocating_for_mem_chunk = g_private_new(NULL);
|
||||
#endif
|
||||
}
|
||||
|
115
glib/gmessages.c
115
glib/gmessages.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -31,7 +35,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef NATIVE_WIN32
|
||||
/* Just use stdio. If we're out of memroy, we're hosed anyway. */
|
||||
/* Just use stdio. If we're out of memory, we're hosed anyway. */
|
||||
#undef write
|
||||
|
||||
static inline int
|
||||
@ -67,6 +71,9 @@ struct _GLogHandler
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
|
||||
static GMutex* g_messages_lock = NULL;
|
||||
|
||||
const gchar *g_log_domain_glib = "GLib";
|
||||
static GLogDomain *g_log_domains = NULL;
|
||||
static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
|
||||
@ -76,20 +83,27 @@ static GErrorFunc glib_error_func = NULL;
|
||||
static GWarningFunc glib_warning_func = NULL;
|
||||
static GPrintFunc glib_message_func = NULL;
|
||||
|
||||
static GPrivate* g_log_depth = NULL;
|
||||
|
||||
|
||||
/* --- functions --- */
|
||||
static inline GLogDomain*
|
||||
g_log_find_domain (const gchar *log_domain)
|
||||
{
|
||||
register GLogDomain *domain;
|
||||
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
domain = g_log_domains;
|
||||
while (domain)
|
||||
{
|
||||
if (strcmp (domain->log_domain, log_domain) == 0)
|
||||
return domain;
|
||||
{
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
return domain;
|
||||
}
|
||||
domain = domain->next;
|
||||
}
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -102,8 +116,11 @@ g_log_domain_new (const gchar *log_domain)
|
||||
domain->log_domain = g_strdup (log_domain);
|
||||
domain->fatal_mask = G_LOG_FATAL_MASK;
|
||||
domain->handlers = NULL;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
domain->next = g_log_domains;
|
||||
g_log_domains = domain;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return domain;
|
||||
}
|
||||
@ -116,7 +133,9 @@ g_log_domain_check_free (GLogDomain *domain)
|
||||
{
|
||||
register GLogDomain *last, *work;
|
||||
|
||||
last = NULL;
|
||||
last = NULL;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
work = g_log_domains;
|
||||
while (work)
|
||||
{
|
||||
@ -131,7 +150,8 @@ g_log_domain_check_free (GLogDomain *domain)
|
||||
break;
|
||||
}
|
||||
work = work->next;
|
||||
}
|
||||
}
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,8 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask)
|
||||
/* remove bogus flag */
|
||||
fatal_mask &= ~G_LOG_FLAG_FATAL;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_mask = g_log_always_fatal;
|
||||
g_log_always_fatal = fatal_mask;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_mask;
|
||||
}
|
||||
@ -223,7 +245,9 @@ g_log_set_handler (const gchar *log_domain,
|
||||
domain = g_log_domain_new (log_domain);
|
||||
|
||||
handler = g_new (GLogHandler, 1);
|
||||
g_mutex_lock (g_messages_lock);
|
||||
handler->id = ++handler_id;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
handler->log_level = log_levels;
|
||||
handler->log_func = log_func;
|
||||
handler->data = user_data;
|
||||
@ -311,19 +335,25 @@ g_logv (const gchar *log_domain,
|
||||
test_level = 1 << i;
|
||||
if (log_level & test_level)
|
||||
{
|
||||
static guint g_log_depth = 0;
|
||||
guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
|
||||
GLogDomain *domain;
|
||||
GLogFunc log_func;
|
||||
gpointer data = NULL;
|
||||
|
||||
domain = g_log_find_domain (log_domain ? log_domain : "");
|
||||
|
||||
if (g_log_depth++)
|
||||
if (depth)
|
||||
test_level |= G_LOG_FLAG_RECURSION;
|
||||
|
||||
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) &
|
||||
test_level) != 0)
|
||||
test_level |= G_LOG_FLAG_FATAL;
|
||||
depth++;
|
||||
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
|
||||
g_log_always_fatal) & test_level) != 0)
|
||||
test_level |= G_LOG_FLAG_FATAL;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
log_func = g_log_domain_get_handler (domain, test_level, &data);
|
||||
log_func (log_domain, test_level, buffer, data);
|
||||
|
||||
@ -332,7 +362,8 @@ g_logv (const gchar *log_domain,
|
||||
if (test_level & G_LOG_FLAG_FATAL)
|
||||
abort ();
|
||||
|
||||
g_log_depth--;
|
||||
depth--;
|
||||
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,8 +393,11 @@ g_log_default_handler (const gchar *log_domain,
|
||||
gint fd;
|
||||
#endif
|
||||
gboolean in_recursion;
|
||||
gboolean is_fatal;
|
||||
|
||||
gboolean is_fatal;
|
||||
GErrorFunc local_glib_error_func;
|
||||
GWarningFunc local_glib_warning_func;
|
||||
GPrintFunc local_glib_message_func;
|
||||
|
||||
in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
|
||||
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
||||
log_level &= G_LOG_LEVEL_MASK;
|
||||
@ -380,13 +414,19 @@ g_log_default_handler (const gchar *log_domain,
|
||||
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
|
||||
#endif
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
local_glib_error_func = glib_error_func;
|
||||
local_glib_warning_func = glib_warning_func;
|
||||
local_glib_message_func = glib_message_func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
switch (log_level)
|
||||
{
|
||||
case G_LOG_LEVEL_ERROR:
|
||||
if (!log_domain && glib_error_func)
|
||||
if (!log_domain && local_glib_error_func)
|
||||
{
|
||||
/* compatibility code */
|
||||
glib_error_func (message);
|
||||
local_glib_error_func (message);
|
||||
return;
|
||||
}
|
||||
/* use write(2) for output, in case we are out of memeory */
|
||||
@ -428,10 +468,10 @@ g_log_default_handler (const gchar *log_domain,
|
||||
write (fd, "\n", 1);
|
||||
break;
|
||||
case G_LOG_LEVEL_WARNING:
|
||||
if (!log_domain && glib_warning_func)
|
||||
if (!log_domain && local_glib_warning_func)
|
||||
{
|
||||
/* compatibility code */
|
||||
glib_warning_func (message);
|
||||
local_glib_warning_func (message);
|
||||
return;
|
||||
}
|
||||
if (log_domain)
|
||||
@ -453,10 +493,10 @@ g_log_default_handler (const gchar *log_domain,
|
||||
write (fd, "\n", 1);
|
||||
break;
|
||||
case G_LOG_LEVEL_MESSAGE:
|
||||
if (!log_domain && glib_message_func)
|
||||
if (!log_domain && local_glib_message_func)
|
||||
{
|
||||
/* compatibility code */
|
||||
glib_message_func (message);
|
||||
local_glib_message_func (message);
|
||||
return;
|
||||
}
|
||||
if (log_domain)
|
||||
@ -553,8 +593,10 @@ g_set_print_handler (GPrintFunc func)
|
||||
{
|
||||
GPrintFunc old_print_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_print_func = glib_print_func;
|
||||
glib_print_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_print_func;
|
||||
}
|
||||
@ -565,6 +607,7 @@ g_print (const gchar *format,
|
||||
{
|
||||
va_list args;
|
||||
gchar *string;
|
||||
GPrintFunc local_glib_print_func;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
@ -572,8 +615,12 @@ g_print (const gchar *format,
|
||||
string = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
if (glib_print_func)
|
||||
glib_print_func (string);
|
||||
g_mutex_lock (g_messages_lock);
|
||||
local_glib_print_func = glib_print_func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
if (local_glib_print_func)
|
||||
local_glib_print_func (string);
|
||||
else
|
||||
{
|
||||
fputs (string, stdout);
|
||||
@ -587,8 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
|
||||
{
|
||||
GPrintFunc old_printerr_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_printerr_func = glib_printerr_func;
|
||||
glib_printerr_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_printerr_func;
|
||||
}
|
||||
@ -599,6 +648,7 @@ g_printerr (const gchar *format,
|
||||
{
|
||||
va_list args;
|
||||
gchar *string;
|
||||
GPrintFunc local_glib_printerr_func;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
@ -606,8 +656,12 @@ g_printerr (const gchar *format,
|
||||
string = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
if (glib_printerr_func)
|
||||
glib_printerr_func (string);
|
||||
g_mutex_lock (g_messages_lock);
|
||||
local_glib_printerr_func = glib_printerr_func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
if (local_glib_printerr_func)
|
||||
local_glib_printerr_func (string);
|
||||
else
|
||||
{
|
||||
fputs (string, stderr);
|
||||
@ -622,9 +676,11 @@ g_set_error_handler (GErrorFunc func)
|
||||
{
|
||||
GErrorFunc old_error_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_error_func = glib_error_func;
|
||||
glib_error_func = func;
|
||||
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_error_func;
|
||||
}
|
||||
|
||||
@ -634,8 +690,10 @@ g_set_warning_handler (GWarningFunc func)
|
||||
{
|
||||
GWarningFunc old_warning_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_warning_func = glib_warning_func;
|
||||
glib_warning_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_warning_func;
|
||||
}
|
||||
@ -646,8 +704,17 @@ g_set_message_handler (GPrintFunc func)
|
||||
{
|
||||
GPrintFunc old_message_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_message_func = glib_message_func;
|
||||
glib_message_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_message_func;
|
||||
}
|
||||
|
||||
void
|
||||
g_messages_init (void)
|
||||
{
|
||||
g_messages_lock = g_mutex_new();
|
||||
g_log_depth = g_private_new(NULL);
|
||||
}
|
||||
|
36
glib/gnode.c
36
glib/gnode.c
@ -19,6 +19,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
/* node allocation
|
||||
@ -34,10 +39,12 @@ struct _GAllocator /* from gmem.c */
|
||||
GNode *free_nodes; /* implementation specific */
|
||||
};
|
||||
|
||||
static G_LOCK_DEFINE(current_allocator);
|
||||
static GAllocator *current_allocator = NULL;
|
||||
|
||||
void
|
||||
g_node_push_allocator (GAllocator *allocator)
|
||||
/* HOLDS: current_allocator_lock */
|
||||
static void
|
||||
g_node_validate_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_return_if_fail (allocator != NULL);
|
||||
g_return_if_fail (allocator->is_unused == TRUE);
|
||||
@ -62,13 +69,22 @@ g_node_push_allocator (GAllocator *allocator)
|
||||
}
|
||||
|
||||
allocator->is_unused = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_node_push_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_node_validate_allocator ( allocator );
|
||||
g_lock (current_allocator);
|
||||
allocator->last = current_allocator;
|
||||
current_allocator = allocator;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_node_pop_allocator (void)
|
||||
{
|
||||
g_lock (current_allocator);
|
||||
if (current_allocator)
|
||||
{
|
||||
GAllocator *allocator;
|
||||
@ -78,6 +94,7 @@ g_node_pop_allocator (void)
|
||||
allocator->last = NULL;
|
||||
allocator->is_unused = TRUE;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
|
||||
@ -87,9 +104,15 @@ g_node_new (gpointer data)
|
||||
{
|
||||
GNode *node;
|
||||
|
||||
g_lock (current_allocator);
|
||||
if (!current_allocator)
|
||||
g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
|
||||
|
||||
{
|
||||
GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
|
||||
1024);
|
||||
g_node_validate_allocator (allocator);
|
||||
allocator->last = NULL;
|
||||
current_allocator = allocator;
|
||||
}
|
||||
if (!current_allocator->free_nodes)
|
||||
node = g_chunk_new (GNode, current_allocator->mem_chunk);
|
||||
else
|
||||
@ -97,6 +120,7 @@ g_node_new (gpointer data)
|
||||
node = current_allocator->free_nodes;
|
||||
current_allocator->free_nodes = node->next;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
@ -122,9 +146,11 @@ g_nodes_free (GNode *node)
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
g_lock (current_allocator);
|
||||
parent->next = current_allocator->free_nodes;
|
||||
current_allocator->free_nodes = node;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
static const guint g_primes[] =
|
||||
|
@ -15,6 +15,11 @@
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
@ -19,6 +19,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#define __gscanner_c__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -30,10 +35,12 @@ struct _GAllocator /* from gmem.c */
|
||||
GSList *free_lists; /* implementation specific */
|
||||
};
|
||||
|
||||
static G_LOCK_DEFINE(current_allocator);
|
||||
static GAllocator *current_allocator = NULL;
|
||||
|
||||
void
|
||||
g_slist_push_allocator (GAllocator *allocator)
|
||||
/* HOLDS: current_allocator_lock */
|
||||
static void
|
||||
g_slist_validate_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_return_if_fail (allocator != NULL);
|
||||
g_return_if_fail (allocator->is_unused == TRUE);
|
||||
@ -58,13 +65,22 @@ g_slist_push_allocator (GAllocator *allocator)
|
||||
}
|
||||
|
||||
allocator->is_unused = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_slist_push_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_slist_validate_allocator (allocator);
|
||||
g_lock (current_allocator);
|
||||
allocator->last = current_allocator;
|
||||
current_allocator = allocator;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_slist_pop_allocator (void)
|
||||
{
|
||||
g_lock (current_allocator);
|
||||
if (current_allocator)
|
||||
{
|
||||
GAllocator *allocator;
|
||||
@ -74,6 +90,7 @@ g_slist_pop_allocator (void)
|
||||
allocator->last = NULL;
|
||||
allocator->is_unused = TRUE;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
GSList*
|
||||
@ -81,9 +98,15 @@ g_slist_alloc (void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
g_lock (current_allocator);
|
||||
if (!current_allocator)
|
||||
g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
|
||||
|
||||
{
|
||||
GAllocator *allocator = g_allocator_new ("GLib default GSList allocator",
|
||||
1024);
|
||||
g_slist_validate_allocator (allocator);
|
||||
allocator->last = NULL;
|
||||
current_allocator = allocator;
|
||||
}
|
||||
if (!current_allocator->free_lists)
|
||||
{
|
||||
list = g_chunk_new (GSList, current_allocator->mem_chunk);
|
||||
@ -103,6 +126,8 @@ g_slist_alloc (void)
|
||||
current_allocator->free_lists = list->next;
|
||||
}
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
|
||||
list->next = NULL;
|
||||
|
||||
return list;
|
||||
@ -114,8 +139,10 @@ g_slist_free (GSList *list)
|
||||
if (list)
|
||||
{
|
||||
list->data = list->next;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +152,10 @@ g_slist_free_1 (GSList *list)
|
||||
if (list)
|
||||
{
|
||||
list->data = NULL;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -208,7 +212,8 @@ g_strtod (const gchar *nptr,
|
||||
gchar*
|
||||
g_strerror (gint errnum)
|
||||
{
|
||||
static char msg[64];
|
||||
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||
char *msg;
|
||||
|
||||
#ifdef HAVE_STRERROR
|
||||
return strerror (errnum);
|
||||
@ -634,7 +639,14 @@ g_strerror (gint errnum)
|
||||
if ((errnum > 0) && (errnum <= sys_nerr))
|
||||
return sys_errlist [errnum];
|
||||
#endif /* NO_SYS_ERRLIST */
|
||||
|
||||
|
||||
msg = g_static_private_get (&msg_private);
|
||||
if( !msg )
|
||||
{
|
||||
msg = g_new( gchar, 64 );
|
||||
g_static_private_set (&msg_private, msg, g_free);
|
||||
}
|
||||
|
||||
sprintf (msg, "unknown error (%d)", errnum);
|
||||
return msg;
|
||||
}
|
||||
@ -642,7 +654,8 @@ g_strerror (gint errnum)
|
||||
gchar*
|
||||
g_strsignal (gint signum)
|
||||
{
|
||||
static char msg[64];
|
||||
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||
char *msg;
|
||||
|
||||
#ifdef HAVE_STRSIGNAL
|
||||
extern char *strsignal (int sig);
|
||||
@ -748,6 +761,13 @@ g_strsignal (gint signum)
|
||||
extern char *sys_siglist[];
|
||||
return sys_siglist [signum];
|
||||
#endif /* NO_SYS_SIGLIST */
|
||||
|
||||
msg = g_static_private_get (&msg_private);
|
||||
if( !msg )
|
||||
{
|
||||
msg = g_new( gchar, 64 );
|
||||
g_static_private_set (&msg_private, msg, g_free);
|
||||
}
|
||||
|
||||
sprintf (msg, "unknown signal (%d)", signum);
|
||||
return msg;
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -43,7 +48,7 @@ struct _GRealString
|
||||
gint alloc;
|
||||
};
|
||||
|
||||
|
||||
static G_LOCK_DEFINE(string_mem_chunk);
|
||||
static GMemChunk *string_mem_chunk = NULL;
|
||||
|
||||
/* Hash Functions.
|
||||
@ -202,12 +207,14 @@ g_string_sized_new (guint dfl_size)
|
||||
{
|
||||
GRealString *string;
|
||||
|
||||
g_lock (string_mem_chunk);
|
||||
if (!string_mem_chunk)
|
||||
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
|
||||
sizeof (GRealString),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
string = g_chunk_new (GRealString, string_mem_chunk);
|
||||
g_unlock (string_mem_chunk);
|
||||
|
||||
string->alloc = 0;
|
||||
string->len = 0;
|
||||
@ -241,7 +248,9 @@ g_string_free (GString *string,
|
||||
if (free_segment)
|
||||
g_free (string->str);
|
||||
|
||||
g_lock (string_mem_chunk);
|
||||
g_mem_chunk_free (string_mem_chunk, string);
|
||||
g_unlock (string_mem_chunk);
|
||||
}
|
||||
|
||||
GString*
|
||||
|
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
18
glib/gtree.c
18
glib/gtree.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -78,6 +83,7 @@ static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
|
||||
static void g_tree_node_check (GTreeNode *node);
|
||||
|
||||
|
||||
static G_LOCK_DEFINE(g_tree_global);
|
||||
static GMemChunk *node_mem_chunk = NULL;
|
||||
static GTreeNode *node_free_list = NULL;
|
||||
|
||||
@ -88,6 +94,7 @@ g_tree_node_new (gpointer key,
|
||||
{
|
||||
GTreeNode *node;
|
||||
|
||||
g_lock (g_tree_global);
|
||||
if (node_free_list)
|
||||
{
|
||||
node = node_free_list;
|
||||
@ -102,7 +109,8 @@ g_tree_node_new (gpointer key,
|
||||
G_ALLOC_ONLY);
|
||||
|
||||
node = g_chunk_new (GTreeNode, node_mem_chunk);
|
||||
}
|
||||
}
|
||||
g_unlock (g_tree_global);
|
||||
|
||||
node->balance = 0;
|
||||
node->left = NULL;
|
||||
@ -120,9 +128,11 @@ g_tree_node_destroy (GTreeNode *node)
|
||||
{
|
||||
g_tree_node_destroy (node->right);
|
||||
g_tree_node_destroy (node->left);
|
||||
g_lock (g_tree_global);
|
||||
node->right = node_free_list;
|
||||
node_free_list = node;
|
||||
}
|
||||
g_unlock (g_tree_global);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -375,9 +385,11 @@ g_tree_node_remove (GTreeNode *node,
|
||||
node = g_tree_node_restore_right_balance (new_root, old_balance);
|
||||
}
|
||||
|
||||
g_lock (g_tree_global);
|
||||
garbage->right = node_free_list;
|
||||
node_free_list = garbage;
|
||||
}
|
||||
g_unlock (g_tree_global);
|
||||
}
|
||||
else if (cmp < 0)
|
||||
{
|
||||
if (node->left)
|
||||
|
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe for the unix part, FIXME: make the win32 part MT safe as well.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -367,11 +371,14 @@ g_getenv (const gchar *variable)
|
||||
#endif
|
||||
}
|
||||
|
||||
static G_LOCK_DEFINE(g_utils_global);
|
||||
|
||||
static gchar *g_tmp_dir = NULL;
|
||||
static gchar *g_user_name = NULL;
|
||||
static gchar *g_real_name = NULL;
|
||||
static gchar *g_home_dir = NULL;
|
||||
|
||||
/* HOLDS: g_utils_global_lock */
|
||||
static void
|
||||
g_get_any_init (void)
|
||||
{
|
||||
@ -442,14 +449,16 @@ g_get_any_init (void)
|
||||
g_home_dir = NULL;
|
||||
# endif /* !NATIVE_WIN32 */
|
||||
#endif /* !HAVE_PWD_H */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gchar*
|
||||
g_get_user_name (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_user_name;
|
||||
}
|
||||
@ -457,9 +466,11 @@ g_get_user_name (void)
|
||||
gchar*
|
||||
g_get_real_name (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_real_name;
|
||||
}
|
||||
|
||||
@ -472,8 +483,10 @@ g_get_real_name (void)
|
||||
gchar*
|
||||
g_get_home_dir (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_home_dir;
|
||||
}
|
||||
@ -488,8 +501,10 @@ g_get_home_dir (void)
|
||||
gchar*
|
||||
g_get_tmp_dir (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_tmp_dir;
|
||||
}
|
||||
@ -499,16 +514,25 @@ static gchar *g_prgname = NULL;
|
||||
gchar*
|
||||
g_get_prgname (void)
|
||||
{
|
||||
return g_prgname;
|
||||
gchar* retval;
|
||||
|
||||
g_lock (g_utils_global);
|
||||
retval = g_prgname;
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
g_set_prgname (const gchar *prgname)
|
||||
{
|
||||
gchar *c = g_prgname;
|
||||
|
||||
gchar *c;
|
||||
|
||||
g_lock (g_utils_global);
|
||||
c = g_prgname;
|
||||
g_prgname = g_strdup (prgname);
|
||||
g_free (c);
|
||||
g_unlock (g_utils_global);
|
||||
}
|
||||
|
||||
guint
|
||||
|
44
glist.c
44
glist.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -31,9 +36,11 @@ struct _GAllocator /* from gmem.c */
|
||||
};
|
||||
|
||||
static GAllocator *current_allocator = NULL;
|
||||
static G_LOCK_DEFINE(current_allocator);
|
||||
|
||||
void
|
||||
g_list_push_allocator (GAllocator *allocator)
|
||||
/* HOLDS: current_allocator_lock */
|
||||
static void
|
||||
g_list_validate_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_return_if_fail (allocator != NULL);
|
||||
g_return_if_fail (allocator->is_unused == TRUE);
|
||||
@ -58,13 +65,22 @@ g_list_push_allocator (GAllocator *allocator)
|
||||
}
|
||||
|
||||
allocator->is_unused = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_list_push_allocator(GAllocator *allocator)
|
||||
{
|
||||
g_list_validate_allocator ( allocator );
|
||||
g_lock (current_allocator);
|
||||
allocator->last = current_allocator;
|
||||
current_allocator = allocator;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_list_pop_allocator (void)
|
||||
{
|
||||
g_lock (current_allocator);
|
||||
if (current_allocator)
|
||||
{
|
||||
GAllocator *allocator;
|
||||
@ -74,6 +90,7 @@ g_list_pop_allocator (void)
|
||||
allocator->last = NULL;
|
||||
allocator->is_unused = TRUE;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
GList*
|
||||
@ -81,9 +98,15 @@ g_list_alloc (void)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_lock (current_allocator);
|
||||
if (!current_allocator)
|
||||
g_list_push_allocator (g_allocator_new ("GLib default GList allocator", 1024));
|
||||
|
||||
{
|
||||
GAllocator *allocator = g_allocator_new ("GLib default GList allocator",
|
||||
1024);
|
||||
g_list_validate_allocator (allocator);
|
||||
allocator->last = NULL;
|
||||
current_allocator = allocator;
|
||||
}
|
||||
if (!current_allocator->free_lists)
|
||||
{
|
||||
list = g_chunk_new (GList, current_allocator->mem_chunk);
|
||||
@ -103,6 +126,7 @@ g_list_alloc (void)
|
||||
current_allocator->free_lists = list->next;
|
||||
}
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
list->next = NULL;
|
||||
list->prev = NULL;
|
||||
|
||||
@ -112,23 +136,31 @@ g_list_alloc (void)
|
||||
void
|
||||
g_list_free (GList *list)
|
||||
{
|
||||
#if 0
|
||||
if (list)
|
||||
{
|
||||
list->data = list->next;
|
||||
list->data = list->next;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
g_list_free_1 (GList *list)
|
||||
{
|
||||
#if 0
|
||||
if (list)
|
||||
{
|
||||
list->data = NULL;
|
||||
list->data = NULL;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
GList*
|
||||
|
158
gmain.c
158
gmain.c
@ -20,9 +20,14 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "config.h"
|
||||
|
||||
/* Types */
|
||||
@ -65,9 +70,12 @@ struct _GPollRec {
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
static void g_main_poll (gint timeout,
|
||||
gboolean use_priority,
|
||||
gint priority);
|
||||
static void g_main_poll (gint timeout,
|
||||
gboolean use_priority,
|
||||
gint priority);
|
||||
static void g_main_poll_add_unlocked (gint priority,
|
||||
GPollFD *fd);
|
||||
|
||||
static gboolean g_timeout_prepare (gpointer source_data,
|
||||
GTimeVal *current_time,
|
||||
gint *timeout);
|
||||
@ -90,6 +98,11 @@ static gboolean g_idle_dispatch (gpointer source_data,
|
||||
static GSList *pending_dispatches = NULL;
|
||||
static GHookList source_list = { 0 };
|
||||
|
||||
/* The following lock is used for both the list of sources
|
||||
* and the list of poll records
|
||||
*/
|
||||
static G_LOCK_DEFINE (main_loop);
|
||||
|
||||
static GSourceFuncs timeout_funcs = {
|
||||
g_timeout_prepare,
|
||||
g_timeout_check,
|
||||
@ -104,6 +117,17 @@ static GSourceFuncs idle_funcs = {
|
||||
(GDestroyNotify)g_free
|
||||
};
|
||||
|
||||
static GPollRec *poll_records = NULL;
|
||||
static GPollRec *poll_free_list = NULL;
|
||||
static GMemChunk *poll_chunk;
|
||||
static guint n_poll_records = 0;
|
||||
|
||||
/* this pipe is used to wake up the main loop when a source is added.
|
||||
*/
|
||||
static gint wake_up_pipe[2] = { -1, -1 };
|
||||
static GPollFD wake_up_rec;
|
||||
static gboolean poll_waiting = FALSE;
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
static GPollFunc poll_func = (GPollFunc)poll;
|
||||
#else
|
||||
@ -205,8 +229,11 @@ g_source_add (gint priority,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
guint return_val;
|
||||
GSource *source;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
if (!source_list.is_setup)
|
||||
g_hook_list_init (&source_list, sizeof(GSource));
|
||||
|
||||
@ -224,31 +251,55 @@ g_source_add (gint priority,
|
||||
if (can_recurse)
|
||||
source->hook.flags |= G_SOURCE_CAN_RECURSE;
|
||||
|
||||
return source->hook.hook_id;
|
||||
return_val = source->hook.hook_id;
|
||||
|
||||
/* Now wake up the main loop if it is waiting in the poll() */
|
||||
|
||||
if (poll_waiting)
|
||||
{
|
||||
poll_waiting = FALSE;
|
||||
write (wake_up_pipe[1], "A", 1);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void
|
||||
g_source_remove (guint tag)
|
||||
{
|
||||
GHook *hook = g_hook_get (&source_list, tag);
|
||||
GHook *hook;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
hook = g_hook_get (&source_list, tag);
|
||||
if (hook)
|
||||
{
|
||||
GSource *source = (GSource *)hook;
|
||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||
g_hook_destroy_link (&source_list, hook);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void
|
||||
g_source_remove_by_user_data (gpointer user_data)
|
||||
{
|
||||
GHook *hook = g_hook_find_data (&source_list, TRUE, user_data);
|
||||
GHook *hook;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
hook = g_hook_find_data (&source_list, TRUE, user_data);
|
||||
if (hook)
|
||||
{
|
||||
GSource *source = (GSource *)hook;
|
||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||
g_hook_destroy_link (&source_list, hook);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -262,7 +313,11 @@ g_source_find_source_data (GHook *hook,
|
||||
void
|
||||
g_source_remove_by_source_data (gpointer source_data)
|
||||
{
|
||||
GHook *hook = g_hook_find (&source_list, TRUE,
|
||||
GHook *hook;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
hook = g_hook_find (&source_list, TRUE,
|
||||
g_source_find_source_data, source_data);
|
||||
if (hook)
|
||||
{
|
||||
@ -270,6 +325,8 @@ g_source_remove_by_source_data (gpointer source_data)
|
||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||
g_hook_destroy_link (&source_list, hook);
|
||||
}
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void g_get_current_time (GTimeVal *result)
|
||||
@ -279,6 +336,7 @@ void g_get_current_time (GTimeVal *result)
|
||||
|
||||
/* Running the main loop */
|
||||
|
||||
/* HOLDS: main_loop_lock */
|
||||
static void
|
||||
g_main_dispatch (GTimeVal *current_time)
|
||||
{
|
||||
@ -294,10 +352,20 @@ g_main_dispatch (GTimeVal *current_time)
|
||||
|
||||
if (G_HOOK_IS_VALID (source))
|
||||
{
|
||||
gboolean (*dispatch) (gpointer, GTimeVal *, gpointer);
|
||||
gpointer hook_data = source->hook.data;
|
||||
gpointer source_data = source->source_data;
|
||||
|
||||
dispatch = ((GSourceFuncs *)source->hook.func)->dispatch;
|
||||
|
||||
source->hook.flags |= G_HOOK_FLAG_IN_CALL;
|
||||
need_destroy = !((GSourceFuncs *)source->hook.func)->dispatch (source->source_data,
|
||||
current_time,
|
||||
source->hook.data);
|
||||
|
||||
g_unlock (main_loop);
|
||||
need_destroy = ! dispatch(source_data,
|
||||
current_time,
|
||||
hook_data);
|
||||
g_lock (main_loop);
|
||||
|
||||
source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
|
||||
|
||||
if (need_destroy)
|
||||
@ -320,10 +388,13 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
gint nready = 0;
|
||||
gint current_priority = 0;
|
||||
gint timeout;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
g_return_val_if_fail (!block || dispatch, FALSE);
|
||||
|
||||
g_get_current_time (¤t_time);
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
/* If recursing, finish up current dispatch, before starting over */
|
||||
if (pending_dispatches)
|
||||
@ -331,6 +402,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
if (dispatch)
|
||||
g_main_dispatch (¤t_time);
|
||||
|
||||
g_unlock (main_loop);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -362,6 +434,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
if (!dispatch)
|
||||
{
|
||||
g_hook_unref (&source_list, hook);
|
||||
g_unlock (main_loop);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@ -426,6 +499,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
else
|
||||
{
|
||||
g_hook_unref (&source_list, hook);
|
||||
g_unlock (main_loop);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -442,10 +516,12 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
||||
{
|
||||
pending_dispatches = g_slist_reverse (pending_dispatches);
|
||||
g_main_dispatch (¤t_time);
|
||||
return TRUE;
|
||||
retval = TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
g_unlock (main_loop);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* See if any events are pending
|
||||
@ -494,11 +570,7 @@ g_main_destroy (GMainLoop *loop)
|
||||
g_free (loop);
|
||||
}
|
||||
|
||||
static GPollRec *poll_records = NULL;
|
||||
static GPollRec *poll_free_list = NULL;
|
||||
static GMemChunk *poll_chunk;
|
||||
static guint n_poll_records = 0;
|
||||
|
||||
/* HOLDS: main_loop_lock */
|
||||
static void
|
||||
g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
{
|
||||
@ -508,6 +580,17 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
gint i;
|
||||
gint npoll;
|
||||
|
||||
if (wake_up_pipe[0] < 0)
|
||||
{
|
||||
if (pipe (wake_up_pipe) < 0)
|
||||
g_error ("Cannot create pipe main loop wake-up: %s\n",
|
||||
g_strerror(errno));
|
||||
|
||||
wake_up_rec.fd = wake_up_pipe[0];
|
||||
wake_up_rec.events = G_IO_IN;
|
||||
g_main_poll_add_unlocked (0, &wake_up_rec);
|
||||
}
|
||||
|
||||
pollrec = poll_records;
|
||||
i = 0;
|
||||
while (pollrec && (!use_priority || priority >= pollrec->priority))
|
||||
@ -520,8 +603,20 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
i++;
|
||||
}
|
||||
|
||||
poll_waiting = TRUE;
|
||||
|
||||
g_unlock (main_loop);
|
||||
npoll = i;
|
||||
(*poll_func) (fd_array, npoll, timeout);
|
||||
g_lock (main_loop);
|
||||
|
||||
if (!poll_waiting)
|
||||
{
|
||||
gchar c;
|
||||
read (wake_up_pipe[0], &c, 1);
|
||||
}
|
||||
else
|
||||
poll_waiting = FALSE;
|
||||
|
||||
pollrec = poll_records;
|
||||
i = 0;
|
||||
@ -538,13 +633,29 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
||||
void
|
||||
g_main_poll_add (gint priority,
|
||||
GPollFD *fd)
|
||||
{
|
||||
g_lock (main_loop);
|
||||
g_main_poll_add_unlocked (priority, fd);
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
g_main_poll_add_unlocked (gint priority,
|
||||
GPollFD *fd)
|
||||
{
|
||||
GPollRec *lastrec, *pollrec, *newrec;
|
||||
|
||||
if (!poll_chunk)
|
||||
poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
|
||||
|
||||
newrec = g_chunk_new (GPollRec, poll_chunk);
|
||||
if (poll_free_list)
|
||||
{
|
||||
newrec = poll_free_list;
|
||||
poll_free_list = newrec->next;
|
||||
}
|
||||
else
|
||||
newrec = g_chunk_new (GPollRec, poll_chunk);
|
||||
|
||||
newrec->fd = fd;
|
||||
newrec->priority = priority;
|
||||
|
||||
@ -564,6 +675,8 @@ g_main_poll_add (gint priority,
|
||||
newrec->next = pollrec;
|
||||
|
||||
n_poll_records++;
|
||||
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void
|
||||
@ -571,6 +684,8 @@ g_main_poll_remove (GPollFD *fd)
|
||||
{
|
||||
GPollRec *pollrec, *lastrec;
|
||||
|
||||
g_lock (main_loop);
|
||||
|
||||
lastrec = NULL;
|
||||
pollrec = poll_records;
|
||||
|
||||
@ -585,12 +700,15 @@ g_main_poll_remove (GPollFD *fd)
|
||||
|
||||
pollrec->next = poll_free_list;
|
||||
poll_free_list = pollrec;
|
||||
|
||||
n_poll_records--;
|
||||
break;
|
||||
}
|
||||
lastrec = pollrec;
|
||||
pollrec = pollrec->next;
|
||||
}
|
||||
|
||||
n_poll_records--;
|
||||
g_unlock (main_loop);
|
||||
}
|
||||
|
||||
void
|
||||
|
89
gmem.c
89
gmem.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -48,8 +52,12 @@
|
||||
*/
|
||||
|
||||
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
|
||||
#define ENTER_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk++
|
||||
#define LEAVE_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk--
|
||||
#define ENTER_MEM_CHUNK_ROUTINE() \
|
||||
g_static_set (allocating_for_mem_chunk, \
|
||||
g_static_get (allocating_for_mem_chunk) + 1)
|
||||
#define ENTER_MEM_CHUNK_ROUTINE() \
|
||||
g_static_set (allocating_for_mem_chunk, \
|
||||
g_static_get (allocating_for_mem_chunk) - 1)
|
||||
#else
|
||||
#define ENTER_MEM_CHUNK_ROUTINE()
|
||||
#define LEAVE_MEM_CHUNK_ROUTINE()
|
||||
@ -117,13 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
|
||||
gchar *addr);
|
||||
|
||||
|
||||
/* here we can't use StaticMutexes, as they depend upon a working
|
||||
* g_malloc, the same holds true for StaticPrivate */
|
||||
static GMutex* mem_chunks_lock = NULL;
|
||||
static GRealMemChunk *mem_chunks = NULL;
|
||||
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
static GMutex* mem_profile_lock;
|
||||
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
|
||||
static gulong allocated_mem = 0;
|
||||
static gulong freed_mem = 0;
|
||||
static gint allocating_for_mem_chunk = 0;
|
||||
static GPrivate* allocating_for_mem_chunk = NULL;
|
||||
#define IS_IN_MEM_CHUNK_ROUTINE() \
|
||||
GPOINTER_TO_UINT (g_static_get (allocating_for_mem_chunk))
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
|
||||
|
||||
@ -174,8 +188,9 @@ g_malloc (gulong size)
|
||||
*t = size;
|
||||
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile_lock);
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
if(!allocating_for_mem_chunk) {
|
||||
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||
# endif
|
||||
if (size <= MEM_PROFILE_TABLE_SIZE - 1)
|
||||
allocations[size-1] += 1;
|
||||
@ -185,6 +200,7 @@ g_malloc (gulong size)
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
}
|
||||
# endif
|
||||
g_mutex_unlock (mem_profile_lock);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
|
||||
@ -237,8 +253,9 @@ g_malloc0 (gulong size)
|
||||
*t = size;
|
||||
|
||||
# ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile_lock);
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
if(!allocating_for_mem_chunk) {
|
||||
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||
# endif
|
||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||
allocations[size-1] += 1;
|
||||
@ -248,8 +265,9 @@ g_malloc0 (gulong size)
|
||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
}
|
||||
# endif
|
||||
g_mutex_unlock (mem_profile_lock);
|
||||
# endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
|
||||
|
||||
return p;
|
||||
@ -286,7 +304,9 @@ g_realloc (gpointer mem,
|
||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile);
|
||||
freed_mem += *t;
|
||||
g_mutex_unlock (mem_profile);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
mem = t;
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
@ -321,8 +341,9 @@ g_realloc (gpointer mem,
|
||||
*t = size;
|
||||
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile_lock);
|
||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
if(!allocating_for_mem_chunk) {
|
||||
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||
#endif
|
||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||
allocations[size-1] += 1;
|
||||
@ -332,6 +353,7 @@ g_realloc (gpointer mem,
|
||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||
}
|
||||
#endif
|
||||
g_mutex_unlock (mem_profile_lock);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
|
||||
@ -352,8 +374,10 @@ g_free (gpointer mem)
|
||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||
size = *t;
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
g_mutex_lock (mem_profile);
|
||||
freed_mem += size;
|
||||
g_mutex_unlock (mem_profile);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
mem = t;
|
||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||
@ -380,19 +404,29 @@ g_mem_profile (void)
|
||||
{
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
gint i;
|
||||
|
||||
gulong local_allocations[MEM_PROFILE_TABLE_SIZE];
|
||||
gulong local_allocated_mem;
|
||||
gulong local_freed_mem;
|
||||
|
||||
g_mutex_lock (mem_profile);
|
||||
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
|
||||
if (allocations[i] > 0)
|
||||
local_allocations[i] = allocations[i];
|
||||
local_allocated_mem = allocated_mem;
|
||||
local_freed_mem = freed_mem;
|
||||
g_mutex_unlock (mem_profile);
|
||||
|
||||
for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++)
|
||||
if (local_allocations[i] > 0)
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
|
||||
"%lu allocations of %d bytes\n", allocations[i], i + 1);
|
||||
"%lu allocations of %d bytes\n", local_allocations[i], i + 1);
|
||||
|
||||
if (allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0)
|
||||
if (local_allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0)
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
|
||||
"%lu allocations of greater than %d bytes\n",
|
||||
allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", allocated_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", freed_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", allocated_mem - freed_mem);
|
||||
local_allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", local_allocated_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", local_freed_mem);
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", local_allocated_mem - local_freed_mem);
|
||||
#endif /* ENABLE_MEM_PROFILE */
|
||||
}
|
||||
|
||||
@ -460,11 +494,13 @@ g_mem_chunk_new (gchar *name,
|
||||
mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
|
||||
*/
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk->next = mem_chunks;
|
||||
mem_chunk->prev = NULL;
|
||||
if (mem_chunks)
|
||||
mem_chunks->prev = mem_chunk;
|
||||
mem_chunks = mem_chunk;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
LEAVE_MEM_CHUNK_ROUTINE();
|
||||
|
||||
@ -497,8 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
|
||||
if (rmem_chunk->prev)
|
||||
rmem_chunk->prev->next = rmem_chunk->next;
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
if (rmem_chunk == mem_chunks)
|
||||
mem_chunks = mem_chunks->next;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
if (rmem_chunk->type == G_ALLOC_AND_FREE)
|
||||
g_tree_destroy (rmem_chunk->mem_tree);
|
||||
@ -826,21 +864,26 @@ g_mem_chunk_info (void)
|
||||
gint count;
|
||||
|
||||
count = 0;
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk = mem_chunks;
|
||||
while (mem_chunk)
|
||||
{
|
||||
count += 1;
|
||||
mem_chunk = mem_chunk->next;
|
||||
}
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count);
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk = mem_chunks;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
|
||||
while (mem_chunk)
|
||||
{
|
||||
g_mem_chunk_print ((GMemChunk*) mem_chunk);
|
||||
mem_chunk = mem_chunk->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -848,7 +891,9 @@ g_blow_chunks (void)
|
||||
{
|
||||
GRealMemChunk *mem_chunk;
|
||||
|
||||
g_mutex_lock (mem_chunks_lock);
|
||||
mem_chunk = mem_chunks;
|
||||
g_mutex_unlock (mem_chunks_lock);
|
||||
while (mem_chunk)
|
||||
{
|
||||
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
|
||||
@ -940,3 +985,13 @@ g_allocator_free (GAllocator *allocator)
|
||||
|
||||
g_free (allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_mem_init (void)
|
||||
{
|
||||
mem_chunks_lock = g_mutex_new();
|
||||
#ifdef ENABLE_MEM_PROFILE
|
||||
mem_profile_lock = g_mutex_new();
|
||||
allocating_for_mem_chunk = g_private_new(NULL);
|
||||
#endif
|
||||
}
|
||||
|
115
gmessages.c
115
gmessages.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -31,7 +35,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef NATIVE_WIN32
|
||||
/* Just use stdio. If we're out of memroy, we're hosed anyway. */
|
||||
/* Just use stdio. If we're out of memory, we're hosed anyway. */
|
||||
#undef write
|
||||
|
||||
static inline int
|
||||
@ -67,6 +71,9 @@ struct _GLogHandler
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
|
||||
static GMutex* g_messages_lock = NULL;
|
||||
|
||||
const gchar *g_log_domain_glib = "GLib";
|
||||
static GLogDomain *g_log_domains = NULL;
|
||||
static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
|
||||
@ -76,20 +83,27 @@ static GErrorFunc glib_error_func = NULL;
|
||||
static GWarningFunc glib_warning_func = NULL;
|
||||
static GPrintFunc glib_message_func = NULL;
|
||||
|
||||
static GPrivate* g_log_depth = NULL;
|
||||
|
||||
|
||||
/* --- functions --- */
|
||||
static inline GLogDomain*
|
||||
g_log_find_domain (const gchar *log_domain)
|
||||
{
|
||||
register GLogDomain *domain;
|
||||
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
domain = g_log_domains;
|
||||
while (domain)
|
||||
{
|
||||
if (strcmp (domain->log_domain, log_domain) == 0)
|
||||
return domain;
|
||||
{
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
return domain;
|
||||
}
|
||||
domain = domain->next;
|
||||
}
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -102,8 +116,11 @@ g_log_domain_new (const gchar *log_domain)
|
||||
domain->log_domain = g_strdup (log_domain);
|
||||
domain->fatal_mask = G_LOG_FATAL_MASK;
|
||||
domain->handlers = NULL;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
domain->next = g_log_domains;
|
||||
g_log_domains = domain;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return domain;
|
||||
}
|
||||
@ -116,7 +133,9 @@ g_log_domain_check_free (GLogDomain *domain)
|
||||
{
|
||||
register GLogDomain *last, *work;
|
||||
|
||||
last = NULL;
|
||||
last = NULL;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
work = g_log_domains;
|
||||
while (work)
|
||||
{
|
||||
@ -131,7 +150,8 @@ g_log_domain_check_free (GLogDomain *domain)
|
||||
break;
|
||||
}
|
||||
work = work->next;
|
||||
}
|
||||
}
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,8 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask)
|
||||
/* remove bogus flag */
|
||||
fatal_mask &= ~G_LOG_FLAG_FATAL;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_mask = g_log_always_fatal;
|
||||
g_log_always_fatal = fatal_mask;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_mask;
|
||||
}
|
||||
@ -223,7 +245,9 @@ g_log_set_handler (const gchar *log_domain,
|
||||
domain = g_log_domain_new (log_domain);
|
||||
|
||||
handler = g_new (GLogHandler, 1);
|
||||
g_mutex_lock (g_messages_lock);
|
||||
handler->id = ++handler_id;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
handler->log_level = log_levels;
|
||||
handler->log_func = log_func;
|
||||
handler->data = user_data;
|
||||
@ -311,19 +335,25 @@ g_logv (const gchar *log_domain,
|
||||
test_level = 1 << i;
|
||||
if (log_level & test_level)
|
||||
{
|
||||
static guint g_log_depth = 0;
|
||||
guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
|
||||
GLogDomain *domain;
|
||||
GLogFunc log_func;
|
||||
gpointer data = NULL;
|
||||
|
||||
domain = g_log_find_domain (log_domain ? log_domain : "");
|
||||
|
||||
if (g_log_depth++)
|
||||
if (depth)
|
||||
test_level |= G_LOG_FLAG_RECURSION;
|
||||
|
||||
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) &
|
||||
test_level) != 0)
|
||||
test_level |= G_LOG_FLAG_FATAL;
|
||||
depth++;
|
||||
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
|
||||
g_log_always_fatal) & test_level) != 0)
|
||||
test_level |= G_LOG_FLAG_FATAL;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
log_func = g_log_domain_get_handler (domain, test_level, &data);
|
||||
log_func (log_domain, test_level, buffer, data);
|
||||
|
||||
@ -332,7 +362,8 @@ g_logv (const gchar *log_domain,
|
||||
if (test_level & G_LOG_FLAG_FATAL)
|
||||
abort ();
|
||||
|
||||
g_log_depth--;
|
||||
depth--;
|
||||
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,8 +393,11 @@ g_log_default_handler (const gchar *log_domain,
|
||||
gint fd;
|
||||
#endif
|
||||
gboolean in_recursion;
|
||||
gboolean is_fatal;
|
||||
|
||||
gboolean is_fatal;
|
||||
GErrorFunc local_glib_error_func;
|
||||
GWarningFunc local_glib_warning_func;
|
||||
GPrintFunc local_glib_message_func;
|
||||
|
||||
in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
|
||||
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
||||
log_level &= G_LOG_LEVEL_MASK;
|
||||
@ -380,13 +414,19 @@ g_log_default_handler (const gchar *log_domain,
|
||||
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
|
||||
#endif
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
local_glib_error_func = glib_error_func;
|
||||
local_glib_warning_func = glib_warning_func;
|
||||
local_glib_message_func = glib_message_func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
switch (log_level)
|
||||
{
|
||||
case G_LOG_LEVEL_ERROR:
|
||||
if (!log_domain && glib_error_func)
|
||||
if (!log_domain && local_glib_error_func)
|
||||
{
|
||||
/* compatibility code */
|
||||
glib_error_func (message);
|
||||
local_glib_error_func (message);
|
||||
return;
|
||||
}
|
||||
/* use write(2) for output, in case we are out of memeory */
|
||||
@ -428,10 +468,10 @@ g_log_default_handler (const gchar *log_domain,
|
||||
write (fd, "\n", 1);
|
||||
break;
|
||||
case G_LOG_LEVEL_WARNING:
|
||||
if (!log_domain && glib_warning_func)
|
||||
if (!log_domain && local_glib_warning_func)
|
||||
{
|
||||
/* compatibility code */
|
||||
glib_warning_func (message);
|
||||
local_glib_warning_func (message);
|
||||
return;
|
||||
}
|
||||
if (log_domain)
|
||||
@ -453,10 +493,10 @@ g_log_default_handler (const gchar *log_domain,
|
||||
write (fd, "\n", 1);
|
||||
break;
|
||||
case G_LOG_LEVEL_MESSAGE:
|
||||
if (!log_domain && glib_message_func)
|
||||
if (!log_domain && local_glib_message_func)
|
||||
{
|
||||
/* compatibility code */
|
||||
glib_message_func (message);
|
||||
local_glib_message_func (message);
|
||||
return;
|
||||
}
|
||||
if (log_domain)
|
||||
@ -553,8 +593,10 @@ g_set_print_handler (GPrintFunc func)
|
||||
{
|
||||
GPrintFunc old_print_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_print_func = glib_print_func;
|
||||
glib_print_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_print_func;
|
||||
}
|
||||
@ -565,6 +607,7 @@ g_print (const gchar *format,
|
||||
{
|
||||
va_list args;
|
||||
gchar *string;
|
||||
GPrintFunc local_glib_print_func;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
@ -572,8 +615,12 @@ g_print (const gchar *format,
|
||||
string = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
if (glib_print_func)
|
||||
glib_print_func (string);
|
||||
g_mutex_lock (g_messages_lock);
|
||||
local_glib_print_func = glib_print_func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
if (local_glib_print_func)
|
||||
local_glib_print_func (string);
|
||||
else
|
||||
{
|
||||
fputs (string, stdout);
|
||||
@ -587,8 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
|
||||
{
|
||||
GPrintFunc old_printerr_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_printerr_func = glib_printerr_func;
|
||||
glib_printerr_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_printerr_func;
|
||||
}
|
||||
@ -599,6 +648,7 @@ g_printerr (const gchar *format,
|
||||
{
|
||||
va_list args;
|
||||
gchar *string;
|
||||
GPrintFunc local_glib_printerr_func;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
@ -606,8 +656,12 @@ g_printerr (const gchar *format,
|
||||
string = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
if (glib_printerr_func)
|
||||
glib_printerr_func (string);
|
||||
g_mutex_lock (g_messages_lock);
|
||||
local_glib_printerr_func = glib_printerr_func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
if (local_glib_printerr_func)
|
||||
local_glib_printerr_func (string);
|
||||
else
|
||||
{
|
||||
fputs (string, stderr);
|
||||
@ -622,9 +676,11 @@ g_set_error_handler (GErrorFunc func)
|
||||
{
|
||||
GErrorFunc old_error_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_error_func = glib_error_func;
|
||||
glib_error_func = func;
|
||||
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_error_func;
|
||||
}
|
||||
|
||||
@ -634,8 +690,10 @@ g_set_warning_handler (GWarningFunc func)
|
||||
{
|
||||
GWarningFunc old_warning_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_warning_func = glib_warning_func;
|
||||
glib_warning_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_warning_func;
|
||||
}
|
||||
@ -646,8 +704,17 @@ g_set_message_handler (GPrintFunc func)
|
||||
{
|
||||
GPrintFunc old_message_func;
|
||||
|
||||
g_mutex_lock (g_messages_lock);
|
||||
old_message_func = glib_message_func;
|
||||
glib_message_func = func;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
|
||||
return old_message_func;
|
||||
}
|
||||
|
||||
void
|
||||
g_messages_init (void)
|
||||
{
|
||||
g_messages_lock = g_mutex_new();
|
||||
g_log_depth = g_private_new(NULL);
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
1998-12-10 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmodule.c: Made it MT safe, the g_module_error() is now thread
|
||||
specific.
|
||||
|
||||
Fri Nov 20 14:43:44 1998 Tim Janik <timj@gtk.org>
|
||||
|
||||
* gmodule.c (_g_module_build_path): added empty default imlementation
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
/* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <dl.h>
|
||||
|
||||
|
||||
|
@ -17,6 +17,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "gmodule.h"
|
||||
#include "gmoduleconf.h"
|
||||
#include <errno.h>
|
||||
@ -59,10 +64,11 @@ static inline GModule* g_module_find_by_name (const gchar *name);
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
const char *g_log_domain_gmodule = "GModule";
|
||||
static GModule *modules = NULL;
|
||||
static GModule *main_module = NULL;
|
||||
static gchar *module_error = NULL;
|
||||
static G_LOCK_DEFINE (g_module_global);
|
||||
const char *g_log_domain_gmodule = "GModule";
|
||||
static GModule *modules = NULL;
|
||||
static GModule *main_module = NULL;
|
||||
static GStaticPrivate module_error_private = G_STATIC_PRIVATE_INIT;
|
||||
|
||||
|
||||
/* --- inline functions --- */
|
||||
@ -70,30 +76,45 @@ static inline GModule*
|
||||
g_module_find_by_handle (gpointer handle)
|
||||
{
|
||||
GModule *module;
|
||||
GModule *retval = NULL;
|
||||
|
||||
g_lock (g_module_global);
|
||||
if (main_module && main_module->handle == handle)
|
||||
return main_module;
|
||||
|
||||
for (module = modules; module; module = module->next)
|
||||
if (handle == module->handle)
|
||||
return module;
|
||||
return NULL;
|
||||
retval = main_module;
|
||||
else
|
||||
for (module = modules; module; module = module->next)
|
||||
if (handle == module->handle)
|
||||
{
|
||||
retval = module;
|
||||
break;
|
||||
}
|
||||
g_unlock (g_module_global);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline GModule*
|
||||
g_module_find_by_name (const gchar *name)
|
||||
{
|
||||
GModule *module;
|
||||
GModule *retval = NULL;
|
||||
|
||||
g_lock (g_module_global);
|
||||
for (module = modules; module; module = module->next)
|
||||
if (strcmp (name, module->file_name) == 0)
|
||||
return module;
|
||||
return NULL;
|
||||
{
|
||||
retval = module;
|
||||
break;
|
||||
}
|
||||
g_unlock (g_module_global);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline void
|
||||
g_module_set_error (const gchar *error)
|
||||
{
|
||||
gchar* module_error = g_static_private_get (&module_error_private);
|
||||
if (module_error)
|
||||
g_free (module_error);
|
||||
if (error)
|
||||
@ -101,6 +122,7 @@ g_module_set_error (const gchar *error)
|
||||
else
|
||||
module_error = NULL;
|
||||
errno = 0;
|
||||
g_static_private_set (&module_error_private, module_error, g_free);
|
||||
}
|
||||
|
||||
|
||||
@ -175,7 +197,8 @@ g_module_open (const gchar *file_name,
|
||||
CHECK_ERROR (NULL);
|
||||
|
||||
if (!file_name)
|
||||
{
|
||||
{
|
||||
g_lock (g_module_global);
|
||||
if (!main_module)
|
||||
{
|
||||
handle = _g_module_self ();
|
||||
@ -190,7 +213,8 @@ g_module_open (const gchar *file_name,
|
||||
main_module->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_unlock (g_module_global);
|
||||
|
||||
return main_module;
|
||||
}
|
||||
|
||||
@ -222,8 +246,8 @@ g_module_open (const gchar *file_name,
|
||||
return module;
|
||||
}
|
||||
|
||||
saved_error = module_error;
|
||||
module_error = NULL;
|
||||
saved_error = g_module_error();
|
||||
g_static_private_set (&module_error_private, NULL, NULL);
|
||||
g_module_set_error (NULL);
|
||||
|
||||
module = g_new (GModule, 1);
|
||||
@ -232,8 +256,10 @@ g_module_open (const gchar *file_name,
|
||||
module->ref_count = 1;
|
||||
module->is_resident = FALSE;
|
||||
module->unload = NULL;
|
||||
g_lock (g_module_global);
|
||||
module->next = modules;
|
||||
modules = module;
|
||||
g_unlock (g_module_global);
|
||||
|
||||
/* check initialization */
|
||||
if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init))
|
||||
@ -286,6 +312,8 @@ g_module_close (GModule *module)
|
||||
GModule *node;
|
||||
|
||||
last = NULL;
|
||||
|
||||
g_lock (g_module_global);
|
||||
node = modules;
|
||||
while (node)
|
||||
{
|
||||
@ -301,6 +329,7 @@ g_module_close (GModule *module)
|
||||
node = last->next;
|
||||
}
|
||||
module->next = NULL;
|
||||
g_unlock (g_module_global);
|
||||
|
||||
_g_module_close (module->handle, FALSE);
|
||||
g_free (module->file_name);
|
||||
@ -308,7 +337,7 @@ g_module_close (GModule *module)
|
||||
g_free (module);
|
||||
}
|
||||
|
||||
return module_error == NULL;
|
||||
return g_module_error() == NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -322,7 +351,7 @@ g_module_make_resident (GModule *module)
|
||||
gchar*
|
||||
g_module_error (void)
|
||||
{
|
||||
return module_error;
|
||||
return g_static_private_get (&module_error_private);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -330,6 +359,7 @@ g_module_symbol (GModule *module,
|
||||
const gchar *symbol_name,
|
||||
gpointer *symbol)
|
||||
{
|
||||
gchar *module_error;
|
||||
if (symbol)
|
||||
*symbol = NULL;
|
||||
CHECK_ERROR (FALSE);
|
||||
@ -350,7 +380,7 @@ g_module_symbol (GModule *module,
|
||||
*symbol = _g_module_symbol (module->handle, symbol_name);
|
||||
#endif /* !G_MODULE_NEED_USCORE */
|
||||
|
||||
if (module_error)
|
||||
if ((module_error = g_module_error()))
|
||||
{
|
||||
gchar *error;
|
||||
|
||||
|
176
gmutex.c
Normal file
176
gmutex.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* gmutex.c: MT safety related functions
|
||||
* Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
|
||||
* Owen Taylor
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
typedef struct _GStaticPrivateNode GStaticPrivateNode;
|
||||
|
||||
struct _GStaticPrivateNode {
|
||||
gpointer data;
|
||||
GDestroyNotify destroy;
|
||||
};
|
||||
|
||||
static void g_static_private_free_data (gpointer data);
|
||||
static void g_thread_fail (void);
|
||||
|
||||
/* Global variables */
|
||||
|
||||
gboolean g_thread_use_default_impl = TRUE;
|
||||
gboolean g_thread_supported = FALSE;
|
||||
|
||||
GThreadFunctions g_thread_functions_for_glib_use = {
|
||||
(GMutex*(*)())g_thread_fail, /* mutex_new */
|
||||
NULL, /* mutex_lock */
|
||||
NULL, /* mutex_trylock */
|
||||
NULL, /* mutex_unlock */
|
||||
NULL, /* mutex_free */
|
||||
(GCond*(*)())g_thread_fail, /* cond_new */
|
||||
NULL, /* cond_signal */
|
||||
NULL, /* cond_broadcast */
|
||||
NULL, /* cond_wait */
|
||||
NULL, /* cond_timed_wait */
|
||||
NULL, /* cond_free */
|
||||
(GPrivate*(*)(GDestroyNotify))g_thread_fail, /* private_new */
|
||||
NULL, /* private_get */
|
||||
NULL, /* private_set */
|
||||
};
|
||||
|
||||
/* Local data */
|
||||
|
||||
static GMutex *g_mutex_protect_static_mutex_allocation = NULL;
|
||||
static GMutex *g_thread_specific_mutex = NULL;
|
||||
static GPrivate *g_thread_specific_private = NULL;
|
||||
|
||||
/* This must be called only once, before any threads are created.
|
||||
* It will only be called from g_thread_init() in -lgthread.
|
||||
*/
|
||||
void
|
||||
g_mutex_init (void)
|
||||
{
|
||||
/* We let the main thread (the one that calls g_thread_init) inherit
|
||||
the data, that it set before calling g_thread_init */
|
||||
gpointer private_old = g_thread_specific_private;
|
||||
g_thread_specific_private = g_private_new (g_static_private_free_data);
|
||||
|
||||
/* we can not use g_private_set here, as g_thread_supported is not
|
||||
yet set TRUE, whereas the private_set function is already set. */
|
||||
g_thread_functions_for_glib_use.private_set (g_thread_specific_private,
|
||||
private_old);
|
||||
|
||||
g_mutex_protect_static_mutex_allocation = g_mutex_new();
|
||||
g_thread_specific_mutex = g_mutex_new();
|
||||
}
|
||||
|
||||
GMutex *
|
||||
g_static_mutex_get_mutex_impl (GMutex** mutex)
|
||||
{
|
||||
if (!g_thread_supported)
|
||||
return NULL;
|
||||
|
||||
g_assert (g_mutex_protect_static_mutex_allocation);
|
||||
|
||||
g_mutex_lock (g_mutex_protect_static_mutex_allocation);
|
||||
|
||||
if (!(*mutex))
|
||||
*mutex = g_mutex_new();
|
||||
|
||||
g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
|
||||
|
||||
return *mutex;
|
||||
}
|
||||
|
||||
gpointer
|
||||
g_static_private_get (GStaticPrivate *private)
|
||||
{
|
||||
GArray *array;
|
||||
|
||||
array = g_private_get (g_thread_specific_private);
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
||||
if (!private->index)
|
||||
return NULL;
|
||||
else if (private->index <= array->len)
|
||||
return g_array_index (array, GStaticPrivateNode, (private->index - 1)).data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
g_static_private_set (GStaticPrivate *private,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
GArray *array;
|
||||
static guint next_index = 0;
|
||||
|
||||
array = g_private_get (g_thread_specific_private);
|
||||
if (!array)
|
||||
{
|
||||
array = g_array_new (FALSE, FALSE, sizeof(GStaticPrivateNode));
|
||||
g_private_set (g_thread_specific_private, array);
|
||||
}
|
||||
|
||||
if (!private->index)
|
||||
{
|
||||
g_mutex_lock (g_thread_specific_mutex);
|
||||
|
||||
if (!private->index)
|
||||
private->index = ++next_index;
|
||||
|
||||
g_mutex_unlock (g_thread_specific_mutex);
|
||||
}
|
||||
|
||||
if (private->index > array->len)
|
||||
g_array_set_size (array, private->index);
|
||||
|
||||
g_array_index (array, GStaticPrivateNode, (private->index - 1)).data = data;
|
||||
g_array_index (array, GStaticPrivateNode, (private->index - 1)).destroy = notify;
|
||||
}
|
||||
|
||||
static void
|
||||
g_static_private_free_data (gpointer data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
GArray* array = data;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < array->len; i++ )
|
||||
{
|
||||
GStaticPrivateNode *node = &g_array_index (array, GStaticPrivateNode, i);
|
||||
if (node->data && node->destroy)
|
||||
node->destroy (node->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_thread_fail (void)
|
||||
{
|
||||
g_error ("The thread system is not yet initialized.");
|
||||
}
|
36
gnode.c
36
gnode.c
@ -19,6 +19,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
/* node allocation
|
||||
@ -34,10 +39,12 @@ struct _GAllocator /* from gmem.c */
|
||||
GNode *free_nodes; /* implementation specific */
|
||||
};
|
||||
|
||||
static G_LOCK_DEFINE(current_allocator);
|
||||
static GAllocator *current_allocator = NULL;
|
||||
|
||||
void
|
||||
g_node_push_allocator (GAllocator *allocator)
|
||||
/* HOLDS: current_allocator_lock */
|
||||
static void
|
||||
g_node_validate_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_return_if_fail (allocator != NULL);
|
||||
g_return_if_fail (allocator->is_unused == TRUE);
|
||||
@ -62,13 +69,22 @@ g_node_push_allocator (GAllocator *allocator)
|
||||
}
|
||||
|
||||
allocator->is_unused = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_node_push_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_node_validate_allocator ( allocator );
|
||||
g_lock (current_allocator);
|
||||
allocator->last = current_allocator;
|
||||
current_allocator = allocator;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_node_pop_allocator (void)
|
||||
{
|
||||
g_lock (current_allocator);
|
||||
if (current_allocator)
|
||||
{
|
||||
GAllocator *allocator;
|
||||
@ -78,6 +94,7 @@ g_node_pop_allocator (void)
|
||||
allocator->last = NULL;
|
||||
allocator->is_unused = TRUE;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
|
||||
@ -87,9 +104,15 @@ g_node_new (gpointer data)
|
||||
{
|
||||
GNode *node;
|
||||
|
||||
g_lock (current_allocator);
|
||||
if (!current_allocator)
|
||||
g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
|
||||
|
||||
{
|
||||
GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
|
||||
1024);
|
||||
g_node_validate_allocator (allocator);
|
||||
allocator->last = NULL;
|
||||
current_allocator = allocator;
|
||||
}
|
||||
if (!current_allocator->free_nodes)
|
||||
node = g_chunk_new (GNode, current_allocator->mem_chunk);
|
||||
else
|
||||
@ -97,6 +120,7 @@ g_node_new (gpointer data)
|
||||
node = current_allocator->free_nodes;
|
||||
current_allocator->free_nodes = node->next;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
@ -122,9 +146,11 @@ g_nodes_free (GNode *node)
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
g_lock (current_allocator);
|
||||
parent->next = current_allocator->free_nodes;
|
||||
current_allocator->free_nodes = node;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
static const guint g_primes[] =
|
||||
|
5
grel.c
5
grel.c
@ -15,6 +15,11 @@
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
@ -19,6 +19,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#define __gscanner_c__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
37
gslist.c
37
gslist.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -30,10 +35,12 @@ struct _GAllocator /* from gmem.c */
|
||||
GSList *free_lists; /* implementation specific */
|
||||
};
|
||||
|
||||
static G_LOCK_DEFINE(current_allocator);
|
||||
static GAllocator *current_allocator = NULL;
|
||||
|
||||
void
|
||||
g_slist_push_allocator (GAllocator *allocator)
|
||||
/* HOLDS: current_allocator_lock */
|
||||
static void
|
||||
g_slist_validate_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_return_if_fail (allocator != NULL);
|
||||
g_return_if_fail (allocator->is_unused == TRUE);
|
||||
@ -58,13 +65,22 @@ g_slist_push_allocator (GAllocator *allocator)
|
||||
}
|
||||
|
||||
allocator->is_unused = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_slist_push_allocator (GAllocator *allocator)
|
||||
{
|
||||
g_slist_validate_allocator (allocator);
|
||||
g_lock (current_allocator);
|
||||
allocator->last = current_allocator;
|
||||
current_allocator = allocator;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
void
|
||||
g_slist_pop_allocator (void)
|
||||
{
|
||||
g_lock (current_allocator);
|
||||
if (current_allocator)
|
||||
{
|
||||
GAllocator *allocator;
|
||||
@ -74,6 +90,7 @@ g_slist_pop_allocator (void)
|
||||
allocator->last = NULL;
|
||||
allocator->is_unused = TRUE;
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
|
||||
GSList*
|
||||
@ -81,9 +98,15 @@ g_slist_alloc (void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
g_lock (current_allocator);
|
||||
if (!current_allocator)
|
||||
g_slist_push_allocator (g_allocator_new ("GLib default GSList allocator", 1024));
|
||||
|
||||
{
|
||||
GAllocator *allocator = g_allocator_new ("GLib default GSList allocator",
|
||||
1024);
|
||||
g_slist_validate_allocator (allocator);
|
||||
allocator->last = NULL;
|
||||
current_allocator = allocator;
|
||||
}
|
||||
if (!current_allocator->free_lists)
|
||||
{
|
||||
list = g_chunk_new (GSList, current_allocator->mem_chunk);
|
||||
@ -103,6 +126,8 @@ g_slist_alloc (void)
|
||||
current_allocator->free_lists = list->next;
|
||||
}
|
||||
}
|
||||
g_unlock (current_allocator);
|
||||
|
||||
list->next = NULL;
|
||||
|
||||
return list;
|
||||
@ -114,8 +139,10 @@ g_slist_free (GSList *list)
|
||||
if (list)
|
||||
{
|
||||
list->data = list->next;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +152,10 @@ g_slist_free_1 (GSList *list)
|
||||
if (list)
|
||||
{
|
||||
list->data = NULL;
|
||||
g_lock (current_allocator);
|
||||
list->next = current_allocator->free_lists;
|
||||
current_allocator->free_lists = list;
|
||||
g_unlock (current_allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
26
gstrfuncs.c
26
gstrfuncs.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -208,7 +212,8 @@ g_strtod (const gchar *nptr,
|
||||
gchar*
|
||||
g_strerror (gint errnum)
|
||||
{
|
||||
static char msg[64];
|
||||
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||
char *msg;
|
||||
|
||||
#ifdef HAVE_STRERROR
|
||||
return strerror (errnum);
|
||||
@ -634,7 +639,14 @@ g_strerror (gint errnum)
|
||||
if ((errnum > 0) && (errnum <= sys_nerr))
|
||||
return sys_errlist [errnum];
|
||||
#endif /* NO_SYS_ERRLIST */
|
||||
|
||||
|
||||
msg = g_static_private_get (&msg_private);
|
||||
if( !msg )
|
||||
{
|
||||
msg = g_new( gchar, 64 );
|
||||
g_static_private_set (&msg_private, msg, g_free);
|
||||
}
|
||||
|
||||
sprintf (msg, "unknown error (%d)", errnum);
|
||||
return msg;
|
||||
}
|
||||
@ -642,7 +654,8 @@ g_strerror (gint errnum)
|
||||
gchar*
|
||||
g_strsignal (gint signum)
|
||||
{
|
||||
static char msg[64];
|
||||
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||
char *msg;
|
||||
|
||||
#ifdef HAVE_STRSIGNAL
|
||||
extern char *strsignal (int sig);
|
||||
@ -748,6 +761,13 @@ g_strsignal (gint signum)
|
||||
extern char *sys_siglist[];
|
||||
return sys_siglist [signum];
|
||||
#endif /* NO_SYS_SIGLIST */
|
||||
|
||||
msg = g_static_private_get (&msg_private);
|
||||
if( !msg )
|
||||
{
|
||||
msg = g_new( gchar, 64 );
|
||||
g_static_private_set (&msg_private, msg, g_free);
|
||||
}
|
||||
|
||||
sprintf (msg, "unknown signal (%d)", signum);
|
||||
return msg;
|
||||
|
11
gstring.c
11
gstring.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -43,7 +48,7 @@ struct _GRealString
|
||||
gint alloc;
|
||||
};
|
||||
|
||||
|
||||
static G_LOCK_DEFINE(string_mem_chunk);
|
||||
static GMemChunk *string_mem_chunk = NULL;
|
||||
|
||||
/* Hash Functions.
|
||||
@ -202,12 +207,14 @@ g_string_sized_new (guint dfl_size)
|
||||
{
|
||||
GRealString *string;
|
||||
|
||||
g_lock (string_mem_chunk);
|
||||
if (!string_mem_chunk)
|
||||
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
|
||||
sizeof (GRealString),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
string = g_chunk_new (GRealString, string_mem_chunk);
|
||||
g_unlock (string_mem_chunk);
|
||||
|
||||
string->alloc = 0;
|
||||
string->len = 0;
|
||||
@ -241,7 +248,9 @@ g_string_free (GString *string,
|
||||
if (free_segment)
|
||||
g_free (string->str);
|
||||
|
||||
g_lock (string_mem_chunk);
|
||||
g_mem_chunk_free (string_mem_chunk, string);
|
||||
g_unlock (string_mem_chunk);
|
||||
}
|
||||
|
||||
GString*
|
||||
|
8
gthread/.cvsignore
Normal file
8
gthread/.cvsignore
Normal file
@ -0,0 +1,8 @@
|
||||
Makefile.in
|
||||
Makefile
|
||||
.deps
|
||||
*.lo
|
||||
*.o
|
||||
.libs
|
||||
*.la
|
||||
testgthread
|
21
gthread/Makefile.am
Normal file
21
gthread/Makefile.am
Normal file
@ -0,0 +1,21 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/gthread -DG_LOG_DOMAIN=g_log_domain_gthread
|
||||
|
||||
EXTRA_DIST = \
|
||||
gthread-posix.c
|
||||
|
||||
libglib = $(top_builddir)/libglib.la # -lglib
|
||||
|
||||
lib_LTLIBRARIES = libgthread.la
|
||||
|
||||
libgthread_la_SOURCES = gthread.c
|
||||
libgthread_la_LDFLAGS = \
|
||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
|
||||
-release $(LT_RELEASE)
|
||||
|
||||
libgthread_la_LIBADD = \
|
||||
@G_THREAD_LIBS@
|
||||
|
||||
noinst_PROGRAMS = testgthread
|
||||
testgthread_LDADD = ../libglib.la libgthread.la
|
28
gthread/gthread-none.c
Normal file
28
gthread/gthread-none.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* gthread.c: fallback thread system implementation
|
||||
* Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
static GThreadFunctions
|
||||
g_mutex_functions_for_glib_use_default; /* is NULLified */
|
218
gthread/gthread-nspr.c
Normal file
218
gthread/gthread-nspr.c
Normal file
@ -0,0 +1,218 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* gthread.c: nspr thread system implementation
|
||||
* Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <prpdce.h>
|
||||
#include <prthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
|
||||
#define STDERR_ASSERT(expr)
|
||||
|
||||
#else /* G_DISABLE_ASSERT */
|
||||
|
||||
#define STDERR_ASSERT(expr) G_STMT_START{ \
|
||||
if (!(expr)) \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_ERROR, \
|
||||
"file %s: line %d: assertion failed: (%s)", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#expr); }G_STMT_END
|
||||
|
||||
#endif /* G_DISABLE_ASSERT */
|
||||
|
||||
/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
|
||||
functions from gmem.c and gmessages.c; */
|
||||
|
||||
static gboolean
|
||||
g_mutex_trylock_nspr_impl (GMutex * mutex)
|
||||
{
|
||||
PRStatus status = PRP_TryLock ((PRLock *) mutex);
|
||||
if (status == PR_SUCCESS)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
g_cond_wait_nspr_impl (GCond * cond,
|
||||
GMutex * entered_mutex)
|
||||
{
|
||||
PRStatus status = PRP_NakedWait ((PRCondVar *) cond,
|
||||
(PRLock *) entered_mutex,
|
||||
PR_INTERVAL_NO_TIMEOUT);
|
||||
g_assert (status == PR_SUCCESS);
|
||||
}
|
||||
|
||||
#define G_MICROSEC 1000000
|
||||
|
||||
static gboolean
|
||||
g_cond_timed_wait_nspr_impl (GCond * cond,
|
||||
GMutex * entered_mutex,
|
||||
GTimeVal * abs_time)
|
||||
{
|
||||
PRStatus status;
|
||||
PRIntervalTime interval;
|
||||
GTimeVal current_time;
|
||||
glong microsecs;
|
||||
|
||||
g_return_val_if_fail (cond != NULL, FALSE);
|
||||
g_return_val_if_fail (entered_mutex != NULL, FALSE);
|
||||
|
||||
g_get_current_time (¤t_time);
|
||||
|
||||
if (abs_time->tv_sec < current_time.tv_sec ||
|
||||
(abs_time->tv_sec == current_time.tv_sec &&
|
||||
abs_time->tv_usec < current_time.tv_usec))
|
||||
return FALSE;
|
||||
|
||||
interval = PR_SecondsToInterval (abs_time->tv_sec - current_time.tv_sec);
|
||||
microsecs = abs_time->tv_usec - current_time.tv_usec;
|
||||
if (microsecs < 0)
|
||||
interval -= PR_MicrosecondsToInterval (-microsecs);
|
||||
else
|
||||
interval += PR_MicrosecondsToInterval (microsecs);
|
||||
|
||||
status = PRP_NakedWait ((PRCondVar *) cond, (PRLock *) entered_mutex,
|
||||
interval);
|
||||
|
||||
g_assert (status == PR_SUCCESS);
|
||||
|
||||
g_get_current_time (¤t_time);
|
||||
|
||||
if (abs_time->tv_sec < current_time.tv_sec ||
|
||||
(abs_time->tv_sec == current_time.tv_sec &&
|
||||
abs_time->tv_usec < current_time.tv_usec))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _GPrivateNSPRData GPrivateNSPRData;
|
||||
struct _GPrivateNSPRData
|
||||
{
|
||||
gpointer data;
|
||||
GDestroyNotify destructor;
|
||||
};
|
||||
|
||||
typedef struct _GPrivateNSPR GPrivateNSPR;
|
||||
struct _GPrivateNSPR
|
||||
{
|
||||
PRUintn private;
|
||||
GDestroyNotify destructor;
|
||||
};
|
||||
|
||||
static GPrivateNSPRData *
|
||||
g_private_nspr_data_constructor (GDestroyNotify destructor, gpointer data)
|
||||
{
|
||||
/* we can not use g_new and friends, as they might use private data by
|
||||
themself */
|
||||
GPrivateNSPRData *private = malloc (sizeof (GPrivateNSPRData));
|
||||
g_assert (private);
|
||||
private->data = data;
|
||||
private->destructor = destructor;
|
||||
|
||||
return private;
|
||||
}
|
||||
|
||||
static void
|
||||
g_private_nspr_data_destructor (gpointer data)
|
||||
{
|
||||
GPrivateNSPRData *private = data;
|
||||
if (private->destructor && private->data)
|
||||
(*private->destructor) (private->data);
|
||||
free (private);
|
||||
}
|
||||
|
||||
static GPrivate *
|
||||
g_private_new_nspr_impl (GDestroyNotify destructor)
|
||||
{
|
||||
GPrivateNSPR *result = g_new (GPrivateNSPR, 1);
|
||||
PRStatus status = PR_NewThreadPrivateIndex (&result->private,
|
||||
g_private_nspr_data_destructor);
|
||||
g_assert (status == PR_SUCCESS);
|
||||
|
||||
result->destructor = destructor;
|
||||
return (GPrivate *) result;
|
||||
}
|
||||
|
||||
/* NOTE: the functions g_private_get and g_private_set may not use
|
||||
functions from gmem.c and gmessages.c */
|
||||
|
||||
static GPrivateNSPRData *
|
||||
g_private_nspr_data_get (GPrivateNSPR * private)
|
||||
{
|
||||
GPrivateNSPRData *data;
|
||||
|
||||
STDERR_ASSERT (private);
|
||||
|
||||
data = PR_GetThreadPrivate (private->private);
|
||||
if (!data)
|
||||
{
|
||||
data = g_private_nspr_data_constructor (private->destructor, NULL);
|
||||
STDERR_ASSERT (PR_SetThreadPrivate (private->private, data)
|
||||
== PR_SUCCESS);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
g_private_set_nspr_impl (GPrivate * private, gpointer value)
|
||||
{
|
||||
if (!private)
|
||||
return;
|
||||
|
||||
g_private_nspr_data_get ((GPrivateNSPR *) private)->data = value;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
g_private_get_nspr_impl (GPrivate * private)
|
||||
{
|
||||
if (!private)
|
||||
return NULL;
|
||||
|
||||
return g_private_nspr_data_get ((GPrivateNSPR *) private)->data;
|
||||
}
|
||||
|
||||
static GThreadFunctions g_thread_functions_for_glib_use_default =
|
||||
{
|
||||
(GMutex * (*)())PR_NewLock,
|
||||
(void (*)(GMutex *)) PR_Lock,
|
||||
g_mutex_trylock_nspr_impl,
|
||||
(void (*)(GMutex *)) PR_Unlock,
|
||||
(void (*)(GMutex *)) PR_DestroyLock,
|
||||
(GCond * (*)())PRP_NewNakedCondVar,
|
||||
(void (*)(GCond *)) PRP_NakedNotify,
|
||||
(void (*)(GCond *)) PRP_NakedBroadcast,
|
||||
g_cond_wait_nspr_impl,
|
||||
g_cond_timed_wait_nspr_impl,
|
||||
(void (*)(GCond *)) PRP_DestroyNakedCondVar,
|
||||
g_private_new_nspr_impl,
|
||||
g_private_get_nspr_impl,
|
||||
g_private_set_nspr_impl
|
||||
};
|
176
gthread/gthread-posix.c
Normal file
176
gthread/gthread-posix.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* gthread.c: posix thread system implementation
|
||||
* Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define posix_print_error( name, num ) \
|
||||
g_error( "file %s: line %d (%s): error %s during %s", \
|
||||
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
|
||||
g_strerror((num)), #name )
|
||||
|
||||
#define posix_check_for_error( what ) G_STMT_START{ \
|
||||
int error = (what); \
|
||||
if( error ) { posix_print_error( what, error ); } \
|
||||
}G_STMT_END
|
||||
|
||||
static GMutex *
|
||||
g_mutex_new_posix_impl (void)
|
||||
{
|
||||
GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
|
||||
posix_check_for_error (pthread_mutex_init ((pthread_mutex_t *) result, NULL));
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
g_mutex_free_posix_impl (GMutex * mutex)
|
||||
{
|
||||
posix_check_for_error (pthread_mutex_destroy ((pthread_mutex_t *) mutex));
|
||||
free (mutex);
|
||||
}
|
||||
|
||||
/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
|
||||
functions from gmem.c and gmessages.c; */
|
||||
|
||||
/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as
|
||||
signature and semantic are right, but without error check then!!!!,
|
||||
we might want to change this therefore. */
|
||||
|
||||
static gboolean
|
||||
g_mutex_trylock_posix_impl (GMutex * mutex)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
|
||||
if (result != EBUSY)
|
||||
return FALSE;
|
||||
|
||||
posix_check_for_error (result);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GCond *
|
||||
g_cond_new_posix_impl (void)
|
||||
{
|
||||
GCond *result = (GCond *) g_new (pthread_cond_t, 1);
|
||||
posix_check_for_error (pthread_cond_init ((pthread_cond_t *) result, NULL));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
|
||||
can be taken directly, as signature and semantic are right, but
|
||||
without error check then!!!!, we might want to change this
|
||||
therfore. */
|
||||
|
||||
#define G_MICROSEC 1000000
|
||||
#define G_NANOSEC 1000000000
|
||||
|
||||
static gboolean
|
||||
g_cond_timed_wait_posix_impl (GCond * cond,
|
||||
GMutex * entered_mutex,
|
||||
GTimeVal * abs_time)
|
||||
{
|
||||
int result;
|
||||
struct timespec end_time;
|
||||
gboolean timed_out;
|
||||
|
||||
g_return_val_if_fail (cond != NULL, FALSE);
|
||||
g_return_val_if_fail (entered_mutex != NULL, FALSE);
|
||||
|
||||
if (!abs_time)
|
||||
{
|
||||
g_cond_wait (cond, entered_mutex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
end_time.tv_sec = abs_time->tv_sec;
|
||||
end_time.tv_nsec = abs_time->tv_usec * (G_NANOSEC / G_MICROSEC);
|
||||
g_assert (end_time.tv_nsec < G_NANOSEC);
|
||||
result = pthread_cond_timedwait ((pthread_cond_t *) cond,
|
||||
(pthread_mutex_t *) entered_mutex,
|
||||
&end_time);
|
||||
timed_out = (result == ETIMEDOUT);
|
||||
if (!timed_out)
|
||||
posix_check_for_error (result);
|
||||
return !timed_out;
|
||||
}
|
||||
|
||||
static void
|
||||
g_cond_free_posix_impl (GCond * cond)
|
||||
{
|
||||
posix_check_for_error (pthread_cond_destroy ((pthread_cond_t *) cond));
|
||||
g_free (cond);
|
||||
}
|
||||
|
||||
static GPrivate *
|
||||
g_private_new_posix_impl (GDestroyNotify destructor)
|
||||
{
|
||||
GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
|
||||
posix_check_for_error (pthread_key_create ((pthread_key_t *) result,
|
||||
destructor));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* NOTE: the functions g_private_get and g_private_set may not use
|
||||
functions from gmem.c and gmessages.c */
|
||||
|
||||
static void
|
||||
g_private_set_posix_impl (GPrivate * private, gpointer value)
|
||||
{
|
||||
if (!private)
|
||||
return;
|
||||
|
||||
pthread_setspecific (*(pthread_key_t *) private, value);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
g_private_get_posix_impl (GPrivate * private)
|
||||
{
|
||||
if (!private)
|
||||
return NULL;
|
||||
|
||||
return pthread_getspecific (*(pthread_key_t *) private);
|
||||
}
|
||||
|
||||
static GThreadFunctions g_thread_functions_for_glib_use_default =
|
||||
{
|
||||
g_mutex_new_posix_impl,
|
||||
(void (*)(GMutex *)) pthread_mutex_lock,
|
||||
g_mutex_trylock_posix_impl,
|
||||
(void (*)(GMutex *)) pthread_mutex_unlock,
|
||||
g_mutex_free_posix_impl,
|
||||
g_cond_new_posix_impl,
|
||||
(void (*)(GCond *)) pthread_cond_signal,
|
||||
(void (*)(GCond *)) pthread_cond_broadcast,
|
||||
(void (*)(GCond *, GMutex *)) pthread_cond_wait,
|
||||
g_cond_timed_wait_posix_impl,
|
||||
g_cond_free_posix_impl,
|
||||
g_private_new_posix_impl,
|
||||
g_private_get_posix_impl,
|
||||
g_private_set_posix_impl
|
||||
};
|
177
gthread/gthread-solaris.c
Normal file
177
gthread/gthread-solaris.c
Normal file
@ -0,0 +1,177 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* gthread.c: solaris thread system implementation
|
||||
* Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include <thread.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define solaris_print_error( name, num ) \
|
||||
g_error( "file %s: line %d (%s): error %s during %s", \
|
||||
__FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \
|
||||
g_strerror((num)), #name )
|
||||
|
||||
#define solaris_check_for_error( what ) G_STMT_START{ \
|
||||
int error = (what); \
|
||||
if( error ) { solaris_print_error( what, error ); } \
|
||||
}G_STMT_END
|
||||
|
||||
static GMutex *
|
||||
g_mutex_new_solaris_impl (void)
|
||||
{
|
||||
GMutex *result = (GMutex *) g_new (mutex_t, 1);
|
||||
solaris_check_for_error (mutex_init ((mutex_t *) result, USYNC_PROCESS, 0));
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
g_mutex_free_solaris_impl (GMutex * mutex)
|
||||
{
|
||||
solaris_check_for_error (mutex_destroy ((mutex_t *) mutex));
|
||||
free (mutex);
|
||||
}
|
||||
|
||||
/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
|
||||
functions from gmem.c and gmessages.c; */
|
||||
|
||||
/* mutex_lock, mutex_unlock can be taken directly, as
|
||||
signature and semantic are right, but without error check then!!!!,
|
||||
we might want to change this therefore. */
|
||||
|
||||
static gboolean
|
||||
g_mutex_trylock_solaris_impl (GMutex * mutex)
|
||||
{
|
||||
int result;
|
||||
result = mutex_trylock ((mutex_t *) mutex);
|
||||
if (result == EBUSY)
|
||||
return FALSE;
|
||||
solaris_check_for_error (result);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GCond *
|
||||
g_cond_new_solaris_impl ()
|
||||
{
|
||||
GCond *result = (GCond *) g_new (cond_t, 1);
|
||||
solaris_check_for_error (cond_init ((cond_t *) result, USYNC_THREAD, 0));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* cond_signal, cond_broadcast and cond_wait
|
||||
can be taken directly, as signature and semantic are right, but
|
||||
without error check then!!!!, we might want to change this
|
||||
therfore. */
|
||||
|
||||
#define G_MICROSEC 1000000
|
||||
#define G_NANOSEC 1000000000
|
||||
|
||||
static gboolean
|
||||
g_cond_timed_wait_solaris_impl (GCond * cond,
|
||||
GMutex * entered_mutex,
|
||||
GTimeVal * abs_time)
|
||||
{
|
||||
int result;
|
||||
timestruc_t end_time;
|
||||
gboolean timed_out;
|
||||
|
||||
g_return_val_if_fail (cond != NULL, FALSE);
|
||||
g_return_val_if_fail (entered_mutex != NULL, FALSE);
|
||||
|
||||
if (!abs_time)
|
||||
{
|
||||
g_cond_wait (cond, entered_mutex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
end_time.tv_sec = abs_time->tv_sec;
|
||||
end_time.tv_nsec = abs_time->tv_usec * (G_NANOSEC / G_MICROSEC);
|
||||
g_assert (end_time.tv_nsec < G_NANOSEC);
|
||||
result = cond_timedwait ((cond_t *) cond, (mutex_t *) entered_mutex,
|
||||
&end_time);
|
||||
timed_out = (result == ETIME);
|
||||
if (!timed_out)
|
||||
solaris_check_for_error (result);
|
||||
return !timed_out;
|
||||
}
|
||||
|
||||
static void
|
||||
g_cond_free_solaris_impl (GCond * cond)
|
||||
{
|
||||
solaris_check_for_error (cond_destroy ((cond_t *) cond));
|
||||
g_free (cond);
|
||||
}
|
||||
|
||||
static GPrivate *
|
||||
g_private_new_solaris_impl (GDestroyNotify destructor)
|
||||
{
|
||||
GPrivate *result = (GPrivate *) g_new (thread_key_t,1);
|
||||
solaris_check_for_error (thr_keycreate ((thread_key_t *) result,
|
||||
destructor));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* NOTE: the functions g_private_get and g_private_set may not use
|
||||
functions from gmem.c and gmessages.c */
|
||||
|
||||
static void
|
||||
g_private_set_solaris_impl (GPrivate * private, gpointer value)
|
||||
{
|
||||
if (!private)
|
||||
return;
|
||||
|
||||
thr_setspecific (*(thread_key_t *) private, value);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
g_private_get_solaris_impl (GPrivate * private)
|
||||
{
|
||||
gpointer result;
|
||||
|
||||
if (!private)
|
||||
return NULL;
|
||||
|
||||
thr_getspecific (*(thread_key_t *) private, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GThreadFunctions g_thread_functions_for_glib_use_default =
|
||||
{
|
||||
g_mutex_new_solaris_impl,
|
||||
(void (*)(GMutex *)) mutex_lock,
|
||||
g_mutex_trylock_solaris_impl,
|
||||
(void (*)(GMutex *)) mutex_unlock,
|
||||
g_mutex_free_solaris_impl,
|
||||
g_cond_new_solaris_impl,
|
||||
(void (*)(GCond *)) cond_signal,
|
||||
(void (*)(GCond *)) cond_broadcast,
|
||||
(void (*)(GCond *, GMutex *)) cond_wait,
|
||||
g_cond_timed_wait_solaris_impl,
|
||||
g_cond_free_solaris_impl,
|
||||
g_private_new_solaris_impl,
|
||||
g_private_get_solaris_impl,
|
||||
g_private_set_solaris_impl
|
||||
};
|
101
gthread/gthread.c
Normal file
101
gthread/gthread.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* gthread.c: thread related functions
|
||||
* Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
static const char *g_log_domain_gthread = "GThread";
|
||||
static gboolean thread_system_already_initialized = FALSE;
|
||||
|
||||
#include G_THREAD_SOURCE
|
||||
|
||||
void g_mutex_init (void);
|
||||
void g_mem_init (void);
|
||||
void g_messages_init (void);
|
||||
|
||||
void
|
||||
g_thread_init(GThreadFunctions* init)
|
||||
{
|
||||
gboolean supported;
|
||||
|
||||
if (thread_system_already_initialized)
|
||||
g_error ("the glib thread system may only be initialized once.");
|
||||
|
||||
thread_system_already_initialized = TRUE;
|
||||
|
||||
if (init == NULL)
|
||||
init = &g_thread_functions_for_glib_use_default;
|
||||
else
|
||||
g_thread_use_default_impl = FALSE;
|
||||
|
||||
g_thread_functions_for_glib_use = *init;
|
||||
|
||||
/* It is important, that g_thread_supported is not set before the
|
||||
thread initialization functions of the different modules are
|
||||
called */
|
||||
|
||||
supported =
|
||||
init->mutex_new &&
|
||||
init->mutex_lock &&
|
||||
init->mutex_trylock &&
|
||||
init->mutex_unlock &&
|
||||
init->mutex_free &&
|
||||
init->cond_new &&
|
||||
init->cond_signal &&
|
||||
init->cond_broadcast &&
|
||||
init->cond_wait &&
|
||||
init->cond_timed_wait &&
|
||||
init->cond_free &&
|
||||
init->private_new &&
|
||||
init->private_get &&
|
||||
init->private_get;
|
||||
|
||||
/* if somebody is calling g_thread_init (), it means that he wants to
|
||||
have thread support, so check this */
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
if (g_thread_use_default_impl)
|
||||
g_error ("Threads are not supported on this platform.");
|
||||
else
|
||||
g_error ("The supplied thread function vector is invalid.");
|
||||
}
|
||||
|
||||
/* now call the thread initialization functions of the different
|
||||
glib modules. BTW: order does matter, g_mutex_init MUST be first */
|
||||
|
||||
g_mutex_init ();
|
||||
g_mem_init ();
|
||||
g_messages_init ();
|
||||
|
||||
/* now we can set g_thread_supported and thus enable all the thread
|
||||
functions */
|
||||
|
||||
g_thread_supported = TRUE;
|
||||
}
|
200
gthread/testgthread.c
Normal file
200
gthread/testgthread.c
Normal file
@ -0,0 +1,200 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#define main testglib_main
|
||||
#include <testglib.c>
|
||||
#undef main
|
||||
|
||||
#define TEST_PRIVATE_THREADS 9
|
||||
#define TEST_PRIVATE_ROUNDS 5
|
||||
|
||||
void
|
||||
test_mutexes ()
|
||||
{
|
||||
GMutex *mutex = NULL;
|
||||
GCond *cond = NULL;
|
||||
GStaticMutex static_mutex = G_STATIC_MUTEX_INIT;
|
||||
G_LOCK_DEFINE (test_me);
|
||||
|
||||
if (g_thread_supported)
|
||||
{
|
||||
mutex = g_mutex_new ();
|
||||
cond = g_cond_new ();
|
||||
}
|
||||
|
||||
g_mutex_lock (mutex);
|
||||
g_mutex_unlock (mutex);
|
||||
|
||||
g_static_mutex_lock (static_mutex);
|
||||
g_static_mutex_unlock (static_mutex);
|
||||
|
||||
g_cond_signal (cond);
|
||||
g_cond_broadcast (cond);
|
||||
|
||||
g_lock (test_me);
|
||||
g_unlock (test_me);
|
||||
|
||||
if (g_thread_supported)
|
||||
{
|
||||
g_cond_free (cond);
|
||||
g_mutex_free (mutex);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(NSPR) /* we are using nspr threads */
|
||||
/* this option must be specified by hand during compile of
|
||||
testgthread. also note, that you have to link with whatever library
|
||||
nspr is building upon, it might otherwise (as on solaris) lead to
|
||||
run time failure, as the mutex functions are defined in libc, but
|
||||
as noops, that will make some nspr assertions fail. */
|
||||
#include <prthread.h>
|
||||
|
||||
gpointer
|
||||
new_thread (GHookFunc func, gpointer data)
|
||||
{
|
||||
PRThread *thread = PR_CreateThread (PR_SYSTEM_THREAD, func, data,
|
||||
PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
|
||||
PR_JOINABLE_THREAD, 0);
|
||||
return thread;
|
||||
}
|
||||
#define join_thread(thread) PR_JoinThread (thread)
|
||||
#define self_thread() PR_GetCurrentThread ()
|
||||
|
||||
#elif defined(DEFAULTMUTEX) /* we are using solaris threads */
|
||||
|
||||
gpointer
|
||||
new_thread (GHookFunc func, gpointer data)
|
||||
{
|
||||
thread_t thread;
|
||||
thr_create (NULL, 0, (void *(*)(void *)) func, data, THR_BOUND, &thread);
|
||||
return GUINT_TO_POINTER (thread);
|
||||
}
|
||||
#define join_thread(thread) \
|
||||
thr_join ((thread_t)GPOINTER_TO_UINT (thread), NULL, NULL)
|
||||
#define self_thread() GUINT_TO_POINTER (thr_self ())
|
||||
|
||||
#elif defined(PTHREAD_MUTEX_INITIALIZER) /* we are using posix threads */
|
||||
gpointer
|
||||
new_thread(GHookFunc func, gpointer data)
|
||||
{
|
||||
pthread_t thread;
|
||||
pthread_attr_t pthread_attr;
|
||||
pthread_attr_init (&pthread_attr);
|
||||
pthread_attr_setdetachstate (&pthread_attr, PTHREAD_CREATE_JOINABLE);
|
||||
pthread_create (&thread, &pthread_attr, (void *(*)(void *)) func, data);
|
||||
return GUINT_TO_POINTER (thread);
|
||||
}
|
||||
#define join_thread(thread) \
|
||||
pthread_join ((pthread_t)GPOINTER_TO_UINT (thread), NULL)
|
||||
#define self_thread() GUINT_TO_POINTER (pthread_self ())
|
||||
|
||||
#else /* we are not having a thread implementation, do nothing */
|
||||
|
||||
#define new_thread(func,data) (NULL)
|
||||
#define join_thread(thread) ((void)0)
|
||||
#define self_thread() NULL
|
||||
|
||||
#endif
|
||||
|
||||
#define G_MICROSEC 1000000
|
||||
|
||||
void
|
||||
wait_thread (double seconds)
|
||||
{
|
||||
GMutex *mutex;
|
||||
GCond *cond;
|
||||
GTimeVal current_time;
|
||||
|
||||
g_get_current_time (¤t_time);
|
||||
mutex = g_mutex_new ();
|
||||
cond = g_cond_new ();
|
||||
|
||||
current_time.tv_sec += (guint) seconds;
|
||||
seconds -= (guint) seconds;
|
||||
current_time.tv_usec += (guint) (seconds * G_MICROSEC);
|
||||
while (current_time.tv_usec >= G_MICROSEC)
|
||||
{
|
||||
current_time.tv_usec -= G_MICROSEC;
|
||||
current_time.tv_sec++;
|
||||
}
|
||||
|
||||
g_mutex_lock (mutex);
|
||||
g_cond_timed_wait (cond, mutex, ¤t_time);
|
||||
g_mutex_unlock (mutex);
|
||||
|
||||
g_mutex_free (mutex);
|
||||
g_cond_free (cond);
|
||||
}
|
||||
|
||||
gpointer
|
||||
private_constructor ()
|
||||
{
|
||||
gpointer *result = g_new (gpointer, 2);
|
||||
result[0] = 0;
|
||||
result[1] = self_thread ();
|
||||
g_print ("allocating data for the thread %p.\n", result[1]);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
private_destructor (gpointer data)
|
||||
{
|
||||
gpointer *real = data;
|
||||
g_print ("freeing data for the thread %p.\n", real[1]);
|
||||
g_free (real);
|
||||
}
|
||||
|
||||
GStaticPrivate private;
|
||||
|
||||
void
|
||||
test_private_func (void *data)
|
||||
{
|
||||
guint i = 0;
|
||||
wait_thread (1);
|
||||
while (i < TEST_PRIVATE_ROUNDS)
|
||||
{
|
||||
guint random_value = rand () % 10000;
|
||||
guint *data = g_static_private_get (&private);
|
||||
if (!data)
|
||||
{
|
||||
data = private_constructor ();
|
||||
g_static_private_set (&private, data, private_destructor);
|
||||
}
|
||||
*data = random_value;
|
||||
wait_thread (.2);
|
||||
g_assert (*(guint *) g_static_private_get (&private) == random_value);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_private ()
|
||||
{
|
||||
int i;
|
||||
gpointer threads[TEST_PRIVATE_THREADS];
|
||||
for (i = 0; i < TEST_PRIVATE_THREADS; i++)
|
||||
{
|
||||
threads[i] = new_thread (test_private_func, (gpointer) i);
|
||||
}
|
||||
for (i = 0; i < TEST_PRIVATE_THREADS; i++)
|
||||
{
|
||||
join_thread (threads[i]);
|
||||
}
|
||||
g_print ("\n");
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
test_mutexes ();
|
||||
|
||||
g_thread_init (NULL);
|
||||
|
||||
test_mutexes ();
|
||||
|
||||
test_private ();
|
||||
|
||||
/* later we might want to start n copies of that */
|
||||
testglib_main (0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
4
gtimer.c
4
gtimer.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
18
gtree.c
18
gtree.c
@ -16,6 +16,11 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
@ -78,6 +83,7 @@ static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
|
||||
static void g_tree_node_check (GTreeNode *node);
|
||||
|
||||
|
||||
static G_LOCK_DEFINE(g_tree_global);
|
||||
static GMemChunk *node_mem_chunk = NULL;
|
||||
static GTreeNode *node_free_list = NULL;
|
||||
|
||||
@ -88,6 +94,7 @@ g_tree_node_new (gpointer key,
|
||||
{
|
||||
GTreeNode *node;
|
||||
|
||||
g_lock (g_tree_global);
|
||||
if (node_free_list)
|
||||
{
|
||||
node = node_free_list;
|
||||
@ -102,7 +109,8 @@ g_tree_node_new (gpointer key,
|
||||
G_ALLOC_ONLY);
|
||||
|
||||
node = g_chunk_new (GTreeNode, node_mem_chunk);
|
||||
}
|
||||
}
|
||||
g_unlock (g_tree_global);
|
||||
|
||||
node->balance = 0;
|
||||
node->left = NULL;
|
||||
@ -120,9 +128,11 @@ g_tree_node_destroy (GTreeNode *node)
|
||||
{
|
||||
g_tree_node_destroy (node->right);
|
||||
g_tree_node_destroy (node->left);
|
||||
g_lock (g_tree_global);
|
||||
node->right = node_free_list;
|
||||
node_free_list = node;
|
||||
}
|
||||
g_unlock (g_tree_global);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -375,9 +385,11 @@ g_tree_node_remove (GTreeNode *node,
|
||||
node = g_tree_node_restore_right_balance (new_root, old_balance);
|
||||
}
|
||||
|
||||
g_lock (g_tree_global);
|
||||
garbage->right = node_free_list;
|
||||
node_free_list = garbage;
|
||||
}
|
||||
g_unlock (g_tree_global);
|
||||
}
|
||||
else if (cmp < 0)
|
||||
{
|
||||
if (node->left)
|
||||
|
34
gutils.c
34
gutils.c
@ -17,6 +17,10 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MT safe for the unix part, FIXME: make the win32 part MT safe as well.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -367,11 +371,14 @@ g_getenv (const gchar *variable)
|
||||
#endif
|
||||
}
|
||||
|
||||
static G_LOCK_DEFINE(g_utils_global);
|
||||
|
||||
static gchar *g_tmp_dir = NULL;
|
||||
static gchar *g_user_name = NULL;
|
||||
static gchar *g_real_name = NULL;
|
||||
static gchar *g_home_dir = NULL;
|
||||
|
||||
/* HOLDS: g_utils_global_lock */
|
||||
static void
|
||||
g_get_any_init (void)
|
||||
{
|
||||
@ -442,14 +449,16 @@ g_get_any_init (void)
|
||||
g_home_dir = NULL;
|
||||
# endif /* !NATIVE_WIN32 */
|
||||
#endif /* !HAVE_PWD_H */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gchar*
|
||||
g_get_user_name (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_user_name;
|
||||
}
|
||||
@ -457,9 +466,11 @@ g_get_user_name (void)
|
||||
gchar*
|
||||
g_get_real_name (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_real_name;
|
||||
}
|
||||
|
||||
@ -472,8 +483,10 @@ g_get_real_name (void)
|
||||
gchar*
|
||||
g_get_home_dir (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_home_dir;
|
||||
}
|
||||
@ -488,8 +501,10 @@ g_get_home_dir (void)
|
||||
gchar*
|
||||
g_get_tmp_dir (void)
|
||||
{
|
||||
g_lock (g_utils_global);
|
||||
if (!g_tmp_dir)
|
||||
g_get_any_init ();
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return g_tmp_dir;
|
||||
}
|
||||
@ -499,16 +514,25 @@ static gchar *g_prgname = NULL;
|
||||
gchar*
|
||||
g_get_prgname (void)
|
||||
{
|
||||
return g_prgname;
|
||||
gchar* retval;
|
||||
|
||||
g_lock (g_utils_global);
|
||||
retval = g_prgname;
|
||||
g_unlock (g_utils_global);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
g_set_prgname (const gchar *prgname)
|
||||
{
|
||||
gchar *c = g_prgname;
|
||||
|
||||
gchar *c;
|
||||
|
||||
g_lock (g_utils_global);
|
||||
c = g_prgname;
|
||||
g_prgname = g_strdup (prgname);
|
||||
g_free (c);
|
||||
g_unlock (g_utils_global);
|
||||
}
|
||||
|
||||
guint
|
||||
|
Loading…
Reference in New Issue
Block a user