mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-09-20 01:06:15 +02: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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* 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>
|
Sat Dec 12 19:08:59 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
* configure.in: always define G_HAVE_INLINE if __cplusplus is
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
# build . first, then SUBDIRS
|
# build . first, then SUBDIRS
|
||||||
SUBDIRS = gmodule docs
|
SUBDIRS = gmodule gthread docs
|
||||||
all-recursive-am: all-am
|
all-recursive-am: all-am
|
||||||
# alpha `automake' supports this better
|
# alpha `automake' supports this better
|
||||||
#SUBDIRS = . gmodule docs
|
#SUBDIRS = . gmodule docs
|
||||||
@ -50,7 +50,8 @@ libglib_la_SOURCES = \
|
|||||||
gstring.c \
|
gstring.c \
|
||||||
gstrfuncs.c \
|
gstrfuncs.c \
|
||||||
gscanner.c \
|
gscanner.c \
|
||||||
gutils.c
|
gutils.c \
|
||||||
|
gmutex.c
|
||||||
|
|
||||||
include_HEADERS = \
|
include_HEADERS = \
|
||||||
glib.h
|
glib.h
|
||||||
|
@ -84,6 +84,8 @@
|
|||||||
#undef WIN32
|
#undef WIN32
|
||||||
#undef NATIVE_WIN32
|
#undef NATIVE_WIN32
|
||||||
|
|
||||||
|
#undef G_THREAD_SOURCE
|
||||||
|
|
||||||
/* #undef PACKAGE */
|
/* #undef PACKAGE */
|
||||||
/* #undef VERSION */
|
/* #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(G_MODULE_NEED_USCORE)
|
||||||
AC_SUBST(GLIB_DEBUG_FLAGS)
|
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([
|
AC_OUTPUT_COMMANDS([
|
||||||
|
|
||||||
## Generate `glibconfig.h' in two cases
|
## Generate `glibconfig.h' in two cases
|
||||||
@ -550,6 +699,9 @@ outfile_EOF
|
|||||||
if test x$glib_values_h = xyes; then
|
if test x$glib_values_h = xyes; then
|
||||||
echo '#include <values.h>' >> $outfile
|
echo '#include <values.h>' >> $outfile
|
||||||
fi
|
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
|
if test x$glib_sys_poll_h = xyes; then
|
||||||
echo '#include <sys/types.h>' >> $outfile
|
echo '#include <sys/types.h>' >> $outfile
|
||||||
echo '#include <sys/poll.h>' >> $outfile
|
echo '#include <sys/poll.h>' >> $outfile
|
||||||
@ -628,6 +780,34 @@ $glib_inline
|
|||||||
#define G_BYTE_ORDER $g_byte_order
|
#define G_BYTE_ORDER $g_byte_order
|
||||||
outfile_EOF
|
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"
|
g_bit_sizes="16 32"
|
||||||
if test -n "$gint64"; then
|
if test -n "$gint64"; then
|
||||||
g_bit_sizes="$g_bit_sizes 64"
|
g_bit_sizes="$g_bit_sizes 64"
|
||||||
@ -841,6 +1021,31 @@ if test x$glib_working_wctype = xno; then
|
|||||||
glib_wc="\$glib_wc
|
glib_wc="\$glib_wc
|
||||||
#define G_HAVE_BROKEN_WCTYPE 1"
|
#define G_HAVE_BROKEN_WCTYPE 1"
|
||||||
fi
|
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([
|
AC_OUTPUT([
|
||||||
@ -848,6 +1053,7 @@ Makefile
|
|||||||
glib-config
|
glib-config
|
||||||
gmodule/gmoduleconf.h
|
gmodule/gmoduleconf.h
|
||||||
gmodule/Makefile
|
gmodule/Makefile
|
||||||
|
gthread/Makefile
|
||||||
docs/Makefile
|
docs/Makefile
|
||||||
],[case "$CONFIG_FILES" in
|
],[case "$CONFIG_FILES" in
|
||||||
*glib-config*)chmod +x glib-config;;
|
*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,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
@ -40,9 +45,8 @@ static gint g_nearest_pow (gint num);
|
|||||||
static void g_array_maybe_expand (GRealArray *array,
|
static void g_array_maybe_expand (GRealArray *array,
|
||||||
gint len);
|
gint len);
|
||||||
|
|
||||||
|
|
||||||
static GMemChunk *array_mem_chunk = NULL;
|
static GMemChunk *array_mem_chunk = NULL;
|
||||||
|
static G_LOCK_DEFINE(array_mem_chunk);
|
||||||
|
|
||||||
GArray*
|
GArray*
|
||||||
g_array_new (gboolean zero_terminated,
|
g_array_new (gboolean zero_terminated,
|
||||||
@ -51,12 +55,14 @@ g_array_new (gboolean zero_terminated,
|
|||||||
{
|
{
|
||||||
GRealArray *array;
|
GRealArray *array;
|
||||||
|
|
||||||
|
g_lock (array_mem_chunk);
|
||||||
if (!array_mem_chunk)
|
if (!array_mem_chunk)
|
||||||
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||||
sizeof (GRealArray),
|
sizeof (GRealArray),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
array = g_chunk_new (GRealArray, array_mem_chunk);
|
array = g_chunk_new (GRealArray, array_mem_chunk);
|
||||||
|
g_unlock (array_mem_chunk);
|
||||||
|
|
||||||
array->data = NULL;
|
array->data = NULL;
|
||||||
array->len = 0;
|
array->len = 0;
|
||||||
@ -75,7 +81,9 @@ g_array_free (GArray *array,
|
|||||||
if (free_segment)
|
if (free_segment)
|
||||||
g_free (array->data);
|
g_free (array->data);
|
||||||
|
|
||||||
|
g_lock (array_mem_chunk);
|
||||||
g_mem_chunk_free (array_mem_chunk, array);
|
g_mem_chunk_free (array_mem_chunk, array);
|
||||||
|
g_unlock (array_mem_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray*
|
GArray*
|
||||||
@ -241,9 +249,8 @@ struct _GRealPtrArray
|
|||||||
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||||
gint len);
|
gint len);
|
||||||
|
|
||||||
|
|
||||||
static GMemChunk *ptr_array_mem_chunk = NULL;
|
static GMemChunk *ptr_array_mem_chunk = NULL;
|
||||||
|
static G_LOCK_DEFINE(ptr_array_mem_chunk);
|
||||||
|
|
||||||
|
|
||||||
GPtrArray*
|
GPtrArray*
|
||||||
@ -251,12 +258,14 @@ g_ptr_array_new (void)
|
|||||||
{
|
{
|
||||||
GRealPtrArray *array;
|
GRealPtrArray *array;
|
||||||
|
|
||||||
|
g_lock (ptr_array_mem_chunk);
|
||||||
if (!ptr_array_mem_chunk)
|
if (!ptr_array_mem_chunk)
|
||||||
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||||
sizeof (GRealPtrArray),
|
sizeof (GRealPtrArray),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
||||||
|
g_unlock (ptr_array_mem_chunk);
|
||||||
|
|
||||||
array->pdata = NULL;
|
array->pdata = NULL;
|
||||||
array->len = 0;
|
array->len = 0;
|
||||||
@ -274,7 +283,9 @@ g_ptr_array_free (GPtrArray *array,
|
|||||||
if (free_segment)
|
if (free_segment)
|
||||||
g_free (array->pdata);
|
g_free (array->pdata);
|
||||||
|
|
||||||
|
g_lock (ptr_array_mem_chunk);
|
||||||
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
||||||
|
g_unlock (ptr_array_mem_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||||
|
* then
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
11
gcache.c
11
gcache.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +61,7 @@ static void g_cache_node_destroy (GCacheNode *node);
|
|||||||
|
|
||||||
|
|
||||||
static GMemChunk *node_mem_chunk = NULL;
|
static GMemChunk *node_mem_chunk = NULL;
|
||||||
|
static G_LOCK_DEFINE(node_mem_chunk);
|
||||||
|
|
||||||
GCache*
|
GCache*
|
||||||
g_cache_new (GCacheNewFunc value_new_func,
|
g_cache_new (GCacheNewFunc value_new_func,
|
||||||
@ -193,11 +198,13 @@ g_cache_node_new (gpointer value)
|
|||||||
{
|
{
|
||||||
GCacheNode *node;
|
GCacheNode *node;
|
||||||
|
|
||||||
|
g_lock (node_mem_chunk);
|
||||||
if (!node_mem_chunk)
|
if (!node_mem_chunk)
|
||||||
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
|
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
node = g_chunk_new (GCacheNode, node_mem_chunk);
|
node = g_chunk_new (GCacheNode, node_mem_chunk);
|
||||||
|
g_unlock (node_mem_chunk);
|
||||||
|
|
||||||
node->value = value;
|
node->value = value;
|
||||||
node->ref_count = 1;
|
node->ref_count = 1;
|
||||||
@ -208,5 +215,7 @@ g_cache_node_new (gpointer value)
|
|||||||
static void
|
static void
|
||||||
g_cache_node_destroy (GCacheNode *node)
|
g_cache_node_destroy (GCacheNode *node)
|
||||||
{
|
{
|
||||||
|
g_lock (node_mem_chunk);
|
||||||
g_mem_chunk_free (node_mem_chunk, node);
|
g_mem_chunk_free (node_mem_chunk, node);
|
||||||
|
g_unlock (node_mem_chunk);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <string.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
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
* 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 <string.h>
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
@ -61,18 +67,24 @@ static inline GQuark g_quark_new (gchar *string);
|
|||||||
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
|
static G_LOCK_DEFINE(g_dataset_global);
|
||||||
static GHashTable *g_dataset_location_ht = NULL;
|
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_dataset_mem_chunk = NULL;
|
||||||
static GMemChunk *g_data_mem_chunk = NULL;
|
static GMemChunk *g_data_mem_chunk = NULL;
|
||||||
static GData *g_data_cache = NULL;
|
static GData *g_data_cache = NULL;
|
||||||
static guint g_data_cache_length = 0;
|
static guint g_data_cache_length = 0;
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_quark_global);
|
||||||
static GHashTable *g_quark_ht = NULL;
|
static GHashTable *g_quark_ht = NULL;
|
||||||
static gchar **g_quarks = NULL;
|
static gchar **g_quarks = NULL;
|
||||||
static GQuark g_quark_seq_id = 0;
|
static GQuark g_quark_seq_id = 0;
|
||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static inline void
|
static inline void
|
||||||
g_datalist_clear_i (GData **datalist)
|
g_datalist_clear_i (GData **datalist)
|
||||||
{
|
{
|
||||||
@ -109,13 +121,16 @@ g_datalist_clear (GData **datalist)
|
|||||||
{
|
{
|
||||||
g_return_if_fail (datalist != NULL);
|
g_return_if_fail (datalist != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (!g_dataset_location_ht)
|
if (!g_dataset_location_ht)
|
||||||
g_data_initialize ();
|
g_data_initialize ();
|
||||||
|
|
||||||
while (*datalist)
|
while (*datalist)
|
||||||
g_datalist_clear_i (datalist);
|
g_datalist_clear_i (datalist);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static inline GDataset*
|
static inline GDataset*
|
||||||
g_dataset_lookup (gconstpointer dataset_location)
|
g_dataset_lookup (gconstpointer dataset_location)
|
||||||
{
|
{
|
||||||
@ -131,6 +146,7 @@ g_dataset_lookup (gconstpointer dataset_location)
|
|||||||
return dataset;
|
return dataset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static void
|
static void
|
||||||
g_dataset_destroy_internal (GDataset *dataset)
|
g_dataset_destroy_internal (GDataset *dataset)
|
||||||
{
|
{
|
||||||
@ -158,6 +174,7 @@ g_dataset_destroy (gconstpointer dataset_location)
|
|||||||
{
|
{
|
||||||
g_return_if_fail (dataset_location != NULL);
|
g_return_if_fail (dataset_location != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (g_dataset_location_ht)
|
if (g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
register GDataset *dataset;
|
register GDataset *dataset;
|
||||||
@ -166,8 +183,10 @@ g_dataset_destroy (gconstpointer dataset_location)
|
|||||||
if (dataset)
|
if (dataset)
|
||||||
g_dataset_destroy_internal (dataset);
|
g_dataset_destroy_internal (dataset);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static inline void
|
static inline void
|
||||||
g_data_set_internal (GData **datalist,
|
g_data_set_internal (GData **datalist,
|
||||||
GQuark key_id,
|
GQuark key_id,
|
||||||
@ -293,9 +312,10 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (!g_dataset_location_ht)
|
if (!g_dataset_location_ht)
|
||||||
g_data_initialize ();
|
g_data_initialize ();
|
||||||
|
|
||||||
dataset = g_dataset_lookup (dataset_location);
|
dataset = g_dataset_lookup (dataset_location);
|
||||||
if (!dataset)
|
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_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -327,10 +348,12 @@ g_datalist_id_set_data_full (GData **datalist,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (!g_dataset_location_ht)
|
if (!g_dataset_location_ht)
|
||||||
g_data_initialize ();
|
g_data_initialize ();
|
||||||
|
|
||||||
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
|
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -339,6 +362,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (dataset_location != NULL);
|
g_return_if_fail (dataset_location != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (key_id && g_dataset_location_ht)
|
if (key_id && g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
GDataset *dataset;
|
GDataset *dataset;
|
||||||
@ -346,7 +370,8 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
|||||||
dataset = g_dataset_lookup (dataset_location);
|
dataset = g_dataset_lookup (dataset_location);
|
||||||
if (dataset)
|
if (dataset)
|
||||||
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
|
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -355,8 +380,10 @@ g_datalist_id_remove_no_notify (GData **datalist,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (datalist != NULL);
|
g_return_if_fail (datalist != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (key_id && g_dataset_location_ht)
|
if (key_id && g_dataset_location_ht)
|
||||||
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
|
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
@ -365,6 +392,7 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (dataset_location != NULL, NULL);
|
g_return_val_if_fail (dataset_location != NULL, NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (key_id && g_dataset_location_ht)
|
if (key_id && g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
register GDataset *dataset;
|
register GDataset *dataset;
|
||||||
@ -376,10 +404,14 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
|||||||
|
|
||||||
for (list = dataset->datalist; list; list = list->next)
|
for (list = dataset->datalist; list; list = list->next)
|
||||||
if (list->id == key_id)
|
if (list->id == key_id)
|
||||||
return list->data;
|
{
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
|
return list->data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,17 +443,23 @@ g_dataset_foreach (gconstpointer dataset_location,
|
|||||||
g_return_if_fail (dataset_location != NULL);
|
g_return_if_fail (dataset_location != NULL);
|
||||||
g_return_if_fail (func != NULL);
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (g_dataset_location_ht)
|
if (g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
dataset = g_dataset_lookup (dataset_location);
|
dataset = g_dataset_lookup (dataset_location);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
if (dataset)
|
if (dataset)
|
||||||
{
|
{
|
||||||
register GData *list;
|
register GData *list;
|
||||||
|
|
||||||
for (list = dataset->datalist; list; list = list->next)
|
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
|
void
|
||||||
@ -446,6 +484,7 @@ g_datalist_init (GData **datalist)
|
|||||||
*datalist = NULL;
|
*datalist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static void
|
static void
|
||||||
g_data_initialize (void)
|
g_data_initialize (void)
|
||||||
{
|
{
|
||||||
@ -468,12 +507,15 @@ g_data_initialize (void)
|
|||||||
GQuark
|
GQuark
|
||||||
g_quark_try_string (const gchar *string)
|
g_quark_try_string (const gchar *string)
|
||||||
{
|
{
|
||||||
|
GQuark quark = 0;
|
||||||
g_return_val_if_fail (string != NULL, 0);
|
g_return_val_if_fail (string != NULL, 0);
|
||||||
|
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (g_quark_ht)
|
if (g_quark_ht)
|
||||||
return (gulong) g_hash_table_lookup (g_quark_ht, string);
|
quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
|
||||||
else
|
g_unlock (g_quark_global);
|
||||||
return 0;
|
|
||||||
|
return quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
@ -483,6 +525,7 @@ g_quark_from_string (const gchar *string)
|
|||||||
|
|
||||||
g_return_val_if_fail (string != NULL, 0);
|
g_return_val_if_fail (string != NULL, 0);
|
||||||
|
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (g_quark_ht)
|
if (g_quark_ht)
|
||||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||||
else
|
else
|
||||||
@ -493,6 +536,7 @@ g_quark_from_string (const gchar *string)
|
|||||||
|
|
||||||
if (!quark)
|
if (!quark)
|
||||||
quark = g_quark_new (g_strdup (string));
|
quark = g_quark_new (g_strdup (string));
|
||||||
|
g_unlock (g_quark_global);
|
||||||
|
|
||||||
return quark;
|
return quark;
|
||||||
}
|
}
|
||||||
@ -504,6 +548,7 @@ g_quark_from_static_string (const gchar *string)
|
|||||||
|
|
||||||
g_return_val_if_fail (string != NULL, 0);
|
g_return_val_if_fail (string != NULL, 0);
|
||||||
|
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (g_quark_ht)
|
if (g_quark_ht)
|
||||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||||
else
|
else
|
||||||
@ -514,19 +559,24 @@ g_quark_from_static_string (const gchar *string)
|
|||||||
|
|
||||||
if (!quark)
|
if (!quark)
|
||||||
quark = g_quark_new ((gchar*) string);
|
quark = g_quark_new ((gchar*) string);
|
||||||
|
g_unlock (g_quark_global);
|
||||||
|
|
||||||
return quark;
|
return quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar*
|
gchar*
|
||||||
g_quark_to_string (GQuark quark)
|
g_quark_to_string (GQuark quark)
|
||||||
{
|
{
|
||||||
|
gchar* result = NULL;
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (quark > 0 && quark <= g_quark_seq_id)
|
if (quark > 0 && quark <= g_quark_seq_id)
|
||||||
return g_quarks[quark - 1];
|
result = g_quarks[quark - 1];
|
||||||
else
|
g_unlock (g_quark_global);
|
||||||
return NULL;
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_quark_global_lock */
|
||||||
static inline GQuark
|
static inline GQuark
|
||||||
g_quark_new (gchar *string)
|
g_quark_new (gchar *string)
|
||||||
{
|
{
|
||||||
|
24
gdate.c
24
gdate.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -383,6 +388,8 @@ g_date_clear (GDate *d, guint ndates)
|
|||||||
memset (d, 0x0, ndates*sizeof (GDate));
|
memset (d, 0x0, ndates*sizeof (GDate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_date_global);
|
||||||
|
|
||||||
/* These are for the parser, output to the user should use *
|
/* These are for the parser, output to the user should use *
|
||||||
* g_date_strftime () - this creates more never-freed memory to annoy
|
* g_date_strftime () - this creates more never-freed memory to annoy
|
||||||
* all those memory debugger users. :-)
|
* all those memory debugger users. :-)
|
||||||
@ -429,6 +436,7 @@ typedef struct _GDateParseTokens GDateParseTokens;
|
|||||||
|
|
||||||
#define NUM_LEN 10
|
#define NUM_LEN 10
|
||||||
|
|
||||||
|
/* HOLDS: g_date_global_lock */
|
||||||
static void
|
static void
|
||||||
g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
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)
|
if (found != NULL)
|
||||||
{
|
{
|
||||||
pt->month = i;
|
pt->month = i;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,12 +510,13 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_date_global_lock */
|
||||||
static void
|
static void
|
||||||
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
|
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
|
||||||
{
|
{
|
||||||
@ -641,6 +650,8 @@ g_date_set_parse (GDate *d,
|
|||||||
/* set invalid */
|
/* set invalid */
|
||||||
g_date_clear (d, 1);
|
g_date_clear (d, 1);
|
||||||
|
|
||||||
|
g_lock (g_date_global);
|
||||||
|
|
||||||
g_date_prepare_to_parse (str, &pt);
|
g_date_prepare_to_parse (str, &pt);
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
@ -649,7 +660,11 @@ g_date_set_parse (GDate *d,
|
|||||||
#endif
|
#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)
|
if (pt.num_ints > 1)
|
||||||
{
|
{
|
||||||
@ -765,6 +780,7 @@ g_date_set_parse (GDate *d,
|
|||||||
else
|
else
|
||||||
g_message ("Rejected DMY %u %u %u", day, m, y);
|
g_message ("Rejected DMY %u %u %u", day, m, y);
|
||||||
#endif
|
#endif
|
||||||
|
g_unlock (g_date_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
5
gerror.c
5
gerror.c
@ -17,6 +17,11 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||||
|
* then
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
13
ghash.c
13
ghash.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#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 void g_hash_nodes_destroy (GHashNode *hash_node);
|
||||||
|
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_hash_global);
|
||||||
|
|
||||||
static GMemChunk *node_mem_chunk = NULL;
|
static GMemChunk *node_mem_chunk = NULL;
|
||||||
static GHashNode *node_free_list = NULL;
|
static GHashNode *node_free_list = NULL;
|
||||||
|
|
||||||
@ -338,6 +345,7 @@ g_hash_node_new (gpointer key,
|
|||||||
{
|
{
|
||||||
GHashNode *hash_node;
|
GHashNode *hash_node;
|
||||||
|
|
||||||
|
g_lock (g_hash_global);
|
||||||
if (node_free_list)
|
if (node_free_list)
|
||||||
{
|
{
|
||||||
hash_node = 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);
|
hash_node = g_chunk_new (GHashNode, node_mem_chunk);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_hash_global);
|
||||||
|
|
||||||
hash_node->key = key;
|
hash_node->key = key;
|
||||||
hash_node->value = value;
|
hash_node->value = value;
|
||||||
@ -363,8 +372,10 @@ g_hash_node_new (gpointer key,
|
|||||||
static void
|
static void
|
||||||
g_hash_node_destroy (GHashNode *hash_node)
|
g_hash_node_destroy (GHashNode *hash_node)
|
||||||
{
|
{
|
||||||
|
g_lock (g_hash_global);
|
||||||
hash_node->next = node_free_list;
|
hash_node->next = node_free_list;
|
||||||
node_free_list = hash_node;
|
node_free_list = hash_node;
|
||||||
|
g_unlock (g_hash_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -380,6 +391,8 @@ g_hash_nodes_destroy (GHashNode *hash_node)
|
|||||||
while (node->next)
|
while (node->next)
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
|
||||||
|
g_lock (g_hash_global);
|
||||||
node->next = node_free_list;
|
node->next = node_free_list;
|
||||||
node_free_list = hash_node;
|
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,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -17,6 +17,7 @@ Options:
|
|||||||
Libraries:
|
Libraries:
|
||||||
glib
|
glib
|
||||||
gmodule
|
gmodule
|
||||||
|
gthread
|
||||||
EOF
|
EOF
|
||||||
exit $1
|
exit $1
|
||||||
}
|
}
|
||||||
@ -69,6 +70,9 @@ while test $# -gt 0; do
|
|||||||
gmodule)
|
gmodule)
|
||||||
lib_gmodule=yes
|
lib_gmodule=yes
|
||||||
;;
|
;;
|
||||||
|
gthread)
|
||||||
|
lib_gthread=yes
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
usage 1 1>&2
|
usage 1 1>&2
|
||||||
;;
|
;;
|
||||||
@ -83,7 +87,11 @@ if test "$echo_exec_prefix" = "yes"; then
|
|||||||
echo $exec_prefix
|
echo $exec_prefix
|
||||||
fi
|
fi
|
||||||
if test "$echo_cflags" = "yes"; then
|
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
|
fi
|
||||||
if test "$echo_libs" = "yes"; then
|
if test "$echo_libs" = "yes"; then
|
||||||
libs=""
|
libs=""
|
||||||
@ -93,5 +101,8 @@ if test "$echo_libs" = "yes"; then
|
|||||||
if test "$lib_gmodule" = "yes"; then
|
if test "$lib_gmodule" = "yes"; then
|
||||||
libs="@G_MODULE_LDFLAGS@ -lgmodule $libs @G_MODULE_LIBS@"
|
libs="@G_MODULE_LDFLAGS@ -lgmodule $libs @G_MODULE_LIBS@"
|
||||||
fi
|
fi
|
||||||
echo "-L@libdir@ $libs"
|
if test "$lib_gthread" = "yes"; then
|
||||||
|
libs="-lgthread $libs @G_THREAD_LIBS@"
|
||||||
|
fi
|
||||||
|
echo -L@libdir@ $libs
|
||||||
fi
|
fi
|
||||||
|
134
glib.h
134
glib.h
@ -2597,6 +2597,140 @@ gint gwin_closedir (DIR *dir);
|
|||||||
|
|
||||||
#endif /* NATIVE_WIN32 */
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
# build . first, then SUBDIRS
|
# build . first, then SUBDIRS
|
||||||
SUBDIRS = gmodule docs
|
SUBDIRS = gmodule gthread docs
|
||||||
all-recursive-am: all-am
|
all-recursive-am: all-am
|
||||||
# alpha `automake' supports this better
|
# alpha `automake' supports this better
|
||||||
#SUBDIRS = . gmodule docs
|
#SUBDIRS = . gmodule docs
|
||||||
@ -50,7 +50,8 @@ libglib_la_SOURCES = \
|
|||||||
gstring.c \
|
gstring.c \
|
||||||
gstrfuncs.c \
|
gstrfuncs.c \
|
||||||
gscanner.c \
|
gscanner.c \
|
||||||
gutils.c
|
gutils.c \
|
||||||
|
gmutex.c
|
||||||
|
|
||||||
include_HEADERS = \
|
include_HEADERS = \
|
||||||
glib.h
|
glib.h
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
@ -40,9 +45,8 @@ static gint g_nearest_pow (gint num);
|
|||||||
static void g_array_maybe_expand (GRealArray *array,
|
static void g_array_maybe_expand (GRealArray *array,
|
||||||
gint len);
|
gint len);
|
||||||
|
|
||||||
|
|
||||||
static GMemChunk *array_mem_chunk = NULL;
|
static GMemChunk *array_mem_chunk = NULL;
|
||||||
|
static G_LOCK_DEFINE(array_mem_chunk);
|
||||||
|
|
||||||
GArray*
|
GArray*
|
||||||
g_array_new (gboolean zero_terminated,
|
g_array_new (gboolean zero_terminated,
|
||||||
@ -51,12 +55,14 @@ g_array_new (gboolean zero_terminated,
|
|||||||
{
|
{
|
||||||
GRealArray *array;
|
GRealArray *array;
|
||||||
|
|
||||||
|
g_lock (array_mem_chunk);
|
||||||
if (!array_mem_chunk)
|
if (!array_mem_chunk)
|
||||||
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||||
sizeof (GRealArray),
|
sizeof (GRealArray),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
array = g_chunk_new (GRealArray, array_mem_chunk);
|
array = g_chunk_new (GRealArray, array_mem_chunk);
|
||||||
|
g_unlock (array_mem_chunk);
|
||||||
|
|
||||||
array->data = NULL;
|
array->data = NULL;
|
||||||
array->len = 0;
|
array->len = 0;
|
||||||
@ -75,7 +81,9 @@ g_array_free (GArray *array,
|
|||||||
if (free_segment)
|
if (free_segment)
|
||||||
g_free (array->data);
|
g_free (array->data);
|
||||||
|
|
||||||
|
g_lock (array_mem_chunk);
|
||||||
g_mem_chunk_free (array_mem_chunk, array);
|
g_mem_chunk_free (array_mem_chunk, array);
|
||||||
|
g_unlock (array_mem_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray*
|
GArray*
|
||||||
@ -241,9 +249,8 @@ struct _GRealPtrArray
|
|||||||
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||||
gint len);
|
gint len);
|
||||||
|
|
||||||
|
|
||||||
static GMemChunk *ptr_array_mem_chunk = NULL;
|
static GMemChunk *ptr_array_mem_chunk = NULL;
|
||||||
|
static G_LOCK_DEFINE(ptr_array_mem_chunk);
|
||||||
|
|
||||||
|
|
||||||
GPtrArray*
|
GPtrArray*
|
||||||
@ -251,12 +258,14 @@ g_ptr_array_new (void)
|
|||||||
{
|
{
|
||||||
GRealPtrArray *array;
|
GRealPtrArray *array;
|
||||||
|
|
||||||
|
g_lock (ptr_array_mem_chunk);
|
||||||
if (!ptr_array_mem_chunk)
|
if (!ptr_array_mem_chunk)
|
||||||
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||||
sizeof (GRealPtrArray),
|
sizeof (GRealPtrArray),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
||||||
|
g_unlock (ptr_array_mem_chunk);
|
||||||
|
|
||||||
array->pdata = NULL;
|
array->pdata = NULL;
|
||||||
array->len = 0;
|
array->len = 0;
|
||||||
@ -274,7 +283,9 @@ g_ptr_array_free (GPtrArray *array,
|
|||||||
if (free_segment)
|
if (free_segment)
|
||||||
g_free (array->pdata);
|
g_free (array->pdata);
|
||||||
|
|
||||||
|
g_lock (ptr_array_mem_chunk);
|
||||||
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
||||||
|
g_unlock (ptr_array_mem_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||||
|
* then
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +61,7 @@ static void g_cache_node_destroy (GCacheNode *node);
|
|||||||
|
|
||||||
|
|
||||||
static GMemChunk *node_mem_chunk = NULL;
|
static GMemChunk *node_mem_chunk = NULL;
|
||||||
|
static G_LOCK_DEFINE(node_mem_chunk);
|
||||||
|
|
||||||
GCache*
|
GCache*
|
||||||
g_cache_new (GCacheNewFunc value_new_func,
|
g_cache_new (GCacheNewFunc value_new_func,
|
||||||
@ -193,11 +198,13 @@ g_cache_node_new (gpointer value)
|
|||||||
{
|
{
|
||||||
GCacheNode *node;
|
GCacheNode *node;
|
||||||
|
|
||||||
|
g_lock (node_mem_chunk);
|
||||||
if (!node_mem_chunk)
|
if (!node_mem_chunk)
|
||||||
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
|
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
node = g_chunk_new (GCacheNode, node_mem_chunk);
|
node = g_chunk_new (GCacheNode, node_mem_chunk);
|
||||||
|
g_unlock (node_mem_chunk);
|
||||||
|
|
||||||
node->value = value;
|
node->value = value;
|
||||||
node->ref_count = 1;
|
node->ref_count = 1;
|
||||||
@ -208,5 +215,7 @@ g_cache_node_new (gpointer value)
|
|||||||
static void
|
static void
|
||||||
g_cache_node_destroy (GCacheNode *node)
|
g_cache_node_destroy (GCacheNode *node)
|
||||||
{
|
{
|
||||||
|
g_lock (node_mem_chunk);
|
||||||
g_mem_chunk_free (node_mem_chunk, node);
|
g_mem_chunk_free (node_mem_chunk, node);
|
||||||
|
g_unlock (node_mem_chunk);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
* 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 <string.h>
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
@ -61,18 +67,24 @@ static inline GQuark g_quark_new (gchar *string);
|
|||||||
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
|
static G_LOCK_DEFINE(g_dataset_global);
|
||||||
static GHashTable *g_dataset_location_ht = NULL;
|
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_dataset_mem_chunk = NULL;
|
||||||
static GMemChunk *g_data_mem_chunk = NULL;
|
static GMemChunk *g_data_mem_chunk = NULL;
|
||||||
static GData *g_data_cache = NULL;
|
static GData *g_data_cache = NULL;
|
||||||
static guint g_data_cache_length = 0;
|
static guint g_data_cache_length = 0;
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_quark_global);
|
||||||
static GHashTable *g_quark_ht = NULL;
|
static GHashTable *g_quark_ht = NULL;
|
||||||
static gchar **g_quarks = NULL;
|
static gchar **g_quarks = NULL;
|
||||||
static GQuark g_quark_seq_id = 0;
|
static GQuark g_quark_seq_id = 0;
|
||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static inline void
|
static inline void
|
||||||
g_datalist_clear_i (GData **datalist)
|
g_datalist_clear_i (GData **datalist)
|
||||||
{
|
{
|
||||||
@ -109,13 +121,16 @@ g_datalist_clear (GData **datalist)
|
|||||||
{
|
{
|
||||||
g_return_if_fail (datalist != NULL);
|
g_return_if_fail (datalist != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (!g_dataset_location_ht)
|
if (!g_dataset_location_ht)
|
||||||
g_data_initialize ();
|
g_data_initialize ();
|
||||||
|
|
||||||
while (*datalist)
|
while (*datalist)
|
||||||
g_datalist_clear_i (datalist);
|
g_datalist_clear_i (datalist);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static inline GDataset*
|
static inline GDataset*
|
||||||
g_dataset_lookup (gconstpointer dataset_location)
|
g_dataset_lookup (gconstpointer dataset_location)
|
||||||
{
|
{
|
||||||
@ -131,6 +146,7 @@ g_dataset_lookup (gconstpointer dataset_location)
|
|||||||
return dataset;
|
return dataset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static void
|
static void
|
||||||
g_dataset_destroy_internal (GDataset *dataset)
|
g_dataset_destroy_internal (GDataset *dataset)
|
||||||
{
|
{
|
||||||
@ -158,6 +174,7 @@ g_dataset_destroy (gconstpointer dataset_location)
|
|||||||
{
|
{
|
||||||
g_return_if_fail (dataset_location != NULL);
|
g_return_if_fail (dataset_location != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (g_dataset_location_ht)
|
if (g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
register GDataset *dataset;
|
register GDataset *dataset;
|
||||||
@ -166,8 +183,10 @@ g_dataset_destroy (gconstpointer dataset_location)
|
|||||||
if (dataset)
|
if (dataset)
|
||||||
g_dataset_destroy_internal (dataset);
|
g_dataset_destroy_internal (dataset);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static inline void
|
static inline void
|
||||||
g_data_set_internal (GData **datalist,
|
g_data_set_internal (GData **datalist,
|
||||||
GQuark key_id,
|
GQuark key_id,
|
||||||
@ -293,9 +312,10 @@ g_dataset_id_set_data_full (gconstpointer dataset_location,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (!g_dataset_location_ht)
|
if (!g_dataset_location_ht)
|
||||||
g_data_initialize ();
|
g_data_initialize ();
|
||||||
|
|
||||||
dataset = g_dataset_lookup (dataset_location);
|
dataset = g_dataset_lookup (dataset_location);
|
||||||
if (!dataset)
|
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_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -327,10 +348,12 @@ g_datalist_id_set_data_full (GData **datalist,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (!g_dataset_location_ht)
|
if (!g_dataset_location_ht)
|
||||||
g_data_initialize ();
|
g_data_initialize ();
|
||||||
|
|
||||||
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
|
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -339,6 +362,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (dataset_location != NULL);
|
g_return_if_fail (dataset_location != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (key_id && g_dataset_location_ht)
|
if (key_id && g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
GDataset *dataset;
|
GDataset *dataset;
|
||||||
@ -346,7 +370,8 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location,
|
|||||||
dataset = g_dataset_lookup (dataset_location);
|
dataset = g_dataset_lookup (dataset_location);
|
||||||
if (dataset)
|
if (dataset)
|
||||||
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
|
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -355,8 +380,10 @@ g_datalist_id_remove_no_notify (GData **datalist,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (datalist != NULL);
|
g_return_if_fail (datalist != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (key_id && g_dataset_location_ht)
|
if (key_id && g_dataset_location_ht)
|
||||||
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
|
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
@ -365,6 +392,7 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (dataset_location != NULL, NULL);
|
g_return_val_if_fail (dataset_location != NULL, NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (key_id && g_dataset_location_ht)
|
if (key_id && g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
register GDataset *dataset;
|
register GDataset *dataset;
|
||||||
@ -376,10 +404,14 @@ g_dataset_id_get_data (gconstpointer dataset_location,
|
|||||||
|
|
||||||
for (list = dataset->datalist; list; list = list->next)
|
for (list = dataset->datalist; list; list = list->next)
|
||||||
if (list->id == key_id)
|
if (list->id == key_id)
|
||||||
return list->data;
|
{
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
|
return list->data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,17 +443,23 @@ g_dataset_foreach (gconstpointer dataset_location,
|
|||||||
g_return_if_fail (dataset_location != NULL);
|
g_return_if_fail (dataset_location != NULL);
|
||||||
g_return_if_fail (func != NULL);
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
|
g_lock (g_dataset_global);
|
||||||
if (g_dataset_location_ht)
|
if (g_dataset_location_ht)
|
||||||
{
|
{
|
||||||
dataset = g_dataset_lookup (dataset_location);
|
dataset = g_dataset_lookup (dataset_location);
|
||||||
|
g_unlock (g_dataset_global);
|
||||||
if (dataset)
|
if (dataset)
|
||||||
{
|
{
|
||||||
register GData *list;
|
register GData *list;
|
||||||
|
|
||||||
for (list = dataset->datalist; list; list = list->next)
|
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
|
void
|
||||||
@ -446,6 +484,7 @@ g_datalist_init (GData **datalist)
|
|||||||
*datalist = NULL;
|
*datalist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_dataset_global_lock */
|
||||||
static void
|
static void
|
||||||
g_data_initialize (void)
|
g_data_initialize (void)
|
||||||
{
|
{
|
||||||
@ -468,12 +507,15 @@ g_data_initialize (void)
|
|||||||
GQuark
|
GQuark
|
||||||
g_quark_try_string (const gchar *string)
|
g_quark_try_string (const gchar *string)
|
||||||
{
|
{
|
||||||
|
GQuark quark = 0;
|
||||||
g_return_val_if_fail (string != NULL, 0);
|
g_return_val_if_fail (string != NULL, 0);
|
||||||
|
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (g_quark_ht)
|
if (g_quark_ht)
|
||||||
return (gulong) g_hash_table_lookup (g_quark_ht, string);
|
quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
|
||||||
else
|
g_unlock (g_quark_global);
|
||||||
return 0;
|
|
||||||
|
return quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
@ -483,6 +525,7 @@ g_quark_from_string (const gchar *string)
|
|||||||
|
|
||||||
g_return_val_if_fail (string != NULL, 0);
|
g_return_val_if_fail (string != NULL, 0);
|
||||||
|
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (g_quark_ht)
|
if (g_quark_ht)
|
||||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||||
else
|
else
|
||||||
@ -493,6 +536,7 @@ g_quark_from_string (const gchar *string)
|
|||||||
|
|
||||||
if (!quark)
|
if (!quark)
|
||||||
quark = g_quark_new (g_strdup (string));
|
quark = g_quark_new (g_strdup (string));
|
||||||
|
g_unlock (g_quark_global);
|
||||||
|
|
||||||
return quark;
|
return quark;
|
||||||
}
|
}
|
||||||
@ -504,6 +548,7 @@ g_quark_from_static_string (const gchar *string)
|
|||||||
|
|
||||||
g_return_val_if_fail (string != NULL, 0);
|
g_return_val_if_fail (string != NULL, 0);
|
||||||
|
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (g_quark_ht)
|
if (g_quark_ht)
|
||||||
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
|
||||||
else
|
else
|
||||||
@ -514,19 +559,24 @@ g_quark_from_static_string (const gchar *string)
|
|||||||
|
|
||||||
if (!quark)
|
if (!quark)
|
||||||
quark = g_quark_new ((gchar*) string);
|
quark = g_quark_new ((gchar*) string);
|
||||||
|
g_unlock (g_quark_global);
|
||||||
|
|
||||||
return quark;
|
return quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar*
|
gchar*
|
||||||
g_quark_to_string (GQuark quark)
|
g_quark_to_string (GQuark quark)
|
||||||
{
|
{
|
||||||
|
gchar* result = NULL;
|
||||||
|
g_lock (g_quark_global);
|
||||||
if (quark > 0 && quark <= g_quark_seq_id)
|
if (quark > 0 && quark <= g_quark_seq_id)
|
||||||
return g_quarks[quark - 1];
|
result = g_quarks[quark - 1];
|
||||||
else
|
g_unlock (g_quark_global);
|
||||||
return NULL;
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_quark_global_lock */
|
||||||
static inline GQuark
|
static inline GQuark
|
||||||
g_quark_new (gchar *string)
|
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,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -383,6 +388,8 @@ g_date_clear (GDate *d, guint ndates)
|
|||||||
memset (d, 0x0, ndates*sizeof (GDate));
|
memset (d, 0x0, ndates*sizeof (GDate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_date_global);
|
||||||
|
|
||||||
/* These are for the parser, output to the user should use *
|
/* These are for the parser, output to the user should use *
|
||||||
* g_date_strftime () - this creates more never-freed memory to annoy
|
* g_date_strftime () - this creates more never-freed memory to annoy
|
||||||
* all those memory debugger users. :-)
|
* all those memory debugger users. :-)
|
||||||
@ -429,6 +436,7 @@ typedef struct _GDateParseTokens GDateParseTokens;
|
|||||||
|
|
||||||
#define NUM_LEN 10
|
#define NUM_LEN 10
|
||||||
|
|
||||||
|
/* HOLDS: g_date_global_lock */
|
||||||
static void
|
static void
|
||||||
g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
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)
|
if (found != NULL)
|
||||||
{
|
{
|
||||||
pt->month = i;
|
pt->month = i;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,12 +510,13 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HOLDS: g_date_global_lock */
|
||||||
static void
|
static void
|
||||||
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
|
g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt)
|
||||||
{
|
{
|
||||||
@ -641,6 +650,8 @@ g_date_set_parse (GDate *d,
|
|||||||
/* set invalid */
|
/* set invalid */
|
||||||
g_date_clear (d, 1);
|
g_date_clear (d, 1);
|
||||||
|
|
||||||
|
g_lock (g_date_global);
|
||||||
|
|
||||||
g_date_prepare_to_parse (str, &pt);
|
g_date_prepare_to_parse (str, &pt);
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
@ -649,7 +660,11 @@ g_date_set_parse (GDate *d,
|
|||||||
#endif
|
#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)
|
if (pt.num_ints > 1)
|
||||||
{
|
{
|
||||||
@ -765,6 +780,7 @@ g_date_set_parse (GDate *d,
|
|||||||
else
|
else
|
||||||
g_message ("Rejected DMY %u %u %u", day, m, y);
|
g_message ("Rejected DMY %u %u %u", day, m, y);
|
||||||
#endif
|
#endif
|
||||||
|
g_unlock (g_date_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
|
||||||
|
* then
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
13
glib/ghash.c
13
glib/ghash.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#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 void g_hash_nodes_destroy (GHashNode *hash_node);
|
||||||
|
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_hash_global);
|
||||||
|
|
||||||
static GMemChunk *node_mem_chunk = NULL;
|
static GMemChunk *node_mem_chunk = NULL;
|
||||||
static GHashNode *node_free_list = NULL;
|
static GHashNode *node_free_list = NULL;
|
||||||
|
|
||||||
@ -338,6 +345,7 @@ g_hash_node_new (gpointer key,
|
|||||||
{
|
{
|
||||||
GHashNode *hash_node;
|
GHashNode *hash_node;
|
||||||
|
|
||||||
|
g_lock (g_hash_global);
|
||||||
if (node_free_list)
|
if (node_free_list)
|
||||||
{
|
{
|
||||||
hash_node = 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);
|
hash_node = g_chunk_new (GHashNode, node_mem_chunk);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_hash_global);
|
||||||
|
|
||||||
hash_node->key = key;
|
hash_node->key = key;
|
||||||
hash_node->value = value;
|
hash_node->value = value;
|
||||||
@ -363,8 +372,10 @@ g_hash_node_new (gpointer key,
|
|||||||
static void
|
static void
|
||||||
g_hash_node_destroy (GHashNode *hash_node)
|
g_hash_node_destroy (GHashNode *hash_node)
|
||||||
{
|
{
|
||||||
|
g_lock (g_hash_global);
|
||||||
hash_node->next = node_free_list;
|
hash_node->next = node_free_list;
|
||||||
node_free_list = hash_node;
|
node_free_list = hash_node;
|
||||||
|
g_unlock (g_hash_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -380,6 +391,8 @@ g_hash_nodes_destroy (GHashNode *hash_node)
|
|||||||
while (node->next)
|
while (node->next)
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
|
||||||
|
g_lock (g_hash_global);
|
||||||
node->next = node_free_list;
|
node->next = node_free_list;
|
||||||
node_free_list = hash_node;
|
node_free_list = hash_node;
|
||||||
|
g_unlock (g_hash_global);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
134
glib/glib.h
134
glib/glib.h
@ -2597,6 +2597,140 @@ gint gwin_closedir (DIR *dir);
|
|||||||
|
|
||||||
#endif /* NATIVE_WIN32 */
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
44
glib/glist.c
44
glib/glist.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -31,9 +36,11 @@ struct _GAllocator /* from gmem.c */
|
|||||||
};
|
};
|
||||||
|
|
||||||
static GAllocator *current_allocator = NULL;
|
static GAllocator *current_allocator = NULL;
|
||||||
|
static G_LOCK_DEFINE(current_allocator);
|
||||||
|
|
||||||
void
|
/* HOLDS: current_allocator_lock */
|
||||||
g_list_push_allocator (GAllocator *allocator)
|
static void
|
||||||
|
g_list_validate_allocator (GAllocator *allocator)
|
||||||
{
|
{
|
||||||
g_return_if_fail (allocator != NULL);
|
g_return_if_fail (allocator != NULL);
|
||||||
g_return_if_fail (allocator->is_unused == TRUE);
|
g_return_if_fail (allocator->is_unused == TRUE);
|
||||||
@ -58,13 +65,22 @@ g_list_push_allocator (GAllocator *allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
allocator->is_unused = FALSE;
|
allocator->is_unused = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_list_push_allocator(GAllocator *allocator)
|
||||||
|
{
|
||||||
|
g_list_validate_allocator ( allocator );
|
||||||
|
g_lock (current_allocator);
|
||||||
allocator->last = current_allocator;
|
allocator->last = current_allocator;
|
||||||
current_allocator = allocator;
|
current_allocator = allocator;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_list_pop_allocator (void)
|
g_list_pop_allocator (void)
|
||||||
{
|
{
|
||||||
|
g_lock (current_allocator);
|
||||||
if (current_allocator)
|
if (current_allocator)
|
||||||
{
|
{
|
||||||
GAllocator *allocator;
|
GAllocator *allocator;
|
||||||
@ -74,6 +90,7 @@ g_list_pop_allocator (void)
|
|||||||
allocator->last = NULL;
|
allocator->last = NULL;
|
||||||
allocator->is_unused = TRUE;
|
allocator->is_unused = TRUE;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
GList*
|
GList*
|
||||||
@ -81,9 +98,15 @@ g_list_alloc (void)
|
|||||||
{
|
{
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
if (!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)
|
if (!current_allocator->free_lists)
|
||||||
{
|
{
|
||||||
list = g_chunk_new (GList, current_allocator->mem_chunk);
|
list = g_chunk_new (GList, current_allocator->mem_chunk);
|
||||||
@ -103,6 +126,7 @@ g_list_alloc (void)
|
|||||||
current_allocator->free_lists = list->next;
|
current_allocator->free_lists = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
list->next = NULL;
|
list->next = NULL;
|
||||||
list->prev = NULL;
|
list->prev = NULL;
|
||||||
|
|
||||||
@ -112,23 +136,31 @@ g_list_alloc (void)
|
|||||||
void
|
void
|
||||||
g_list_free (GList *list)
|
g_list_free (GList *list)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = list->next;
|
list->data = list->next;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_list_free_1 (GList *list)
|
g_list_free_1 (GList *list)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = NULL;
|
list->data = NULL;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GList*
|
GList*
|
||||||
|
158
glib/gmain.c
158
glib/gmain.c
@ -20,9 +20,14 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
@ -65,9 +70,12 @@ struct _GPollRec {
|
|||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
|
|
||||||
static void g_main_poll (gint timeout,
|
static void g_main_poll (gint timeout,
|
||||||
gboolean use_priority,
|
gboolean use_priority,
|
||||||
gint priority);
|
gint priority);
|
||||||
|
static void g_main_poll_add_unlocked (gint priority,
|
||||||
|
GPollFD *fd);
|
||||||
|
|
||||||
static gboolean g_timeout_prepare (gpointer source_data,
|
static gboolean g_timeout_prepare (gpointer source_data,
|
||||||
GTimeVal *current_time,
|
GTimeVal *current_time,
|
||||||
gint *timeout);
|
gint *timeout);
|
||||||
@ -90,6 +98,11 @@ static gboolean g_idle_dispatch (gpointer source_data,
|
|||||||
static GSList *pending_dispatches = NULL;
|
static GSList *pending_dispatches = NULL;
|
||||||
static GHookList source_list = { 0 };
|
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 = {
|
static GSourceFuncs timeout_funcs = {
|
||||||
g_timeout_prepare,
|
g_timeout_prepare,
|
||||||
g_timeout_check,
|
g_timeout_check,
|
||||||
@ -104,6 +117,17 @@ static GSourceFuncs idle_funcs = {
|
|||||||
(GDestroyNotify)g_free
|
(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
|
#ifdef HAVE_POLL
|
||||||
static GPollFunc poll_func = (GPollFunc)poll;
|
static GPollFunc poll_func = (GPollFunc)poll;
|
||||||
#else
|
#else
|
||||||
@ -205,8 +229,11 @@ g_source_add (gint priority,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify notify)
|
GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
|
guint return_val;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
if (!source_list.is_setup)
|
if (!source_list.is_setup)
|
||||||
g_hook_list_init (&source_list, sizeof(GSource));
|
g_hook_list_init (&source_list, sizeof(GSource));
|
||||||
|
|
||||||
@ -224,31 +251,55 @@ g_source_add (gint priority,
|
|||||||
if (can_recurse)
|
if (can_recurse)
|
||||||
source->hook.flags |= G_SOURCE_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
|
void
|
||||||
g_source_remove (guint tag)
|
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)
|
if (hook)
|
||||||
{
|
{
|
||||||
GSource *source = (GSource *)hook;
|
GSource *source = (GSource *)hook;
|
||||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||||
g_hook_destroy_link (&source_list, hook);
|
g_hook_destroy_link (&source_list, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_source_remove_by_user_data (gpointer user_data)
|
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)
|
if (hook)
|
||||||
{
|
{
|
||||||
GSource *source = (GSource *)hook;
|
GSource *source = (GSource *)hook;
|
||||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||||
g_hook_destroy_link (&source_list, hook);
|
g_hook_destroy_link (&source_list, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -262,7 +313,11 @@ g_source_find_source_data (GHook *hook,
|
|||||||
void
|
void
|
||||||
g_source_remove_by_source_data (gpointer source_data)
|
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);
|
g_source_find_source_data, source_data);
|
||||||
if (hook)
|
if (hook)
|
||||||
{
|
{
|
||||||
@ -270,6 +325,8 @@ g_source_remove_by_source_data (gpointer source_data)
|
|||||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||||
g_hook_destroy_link (&source_list, hook);
|
g_hook_destroy_link (&source_list, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_get_current_time (GTimeVal *result)
|
void g_get_current_time (GTimeVal *result)
|
||||||
@ -279,6 +336,7 @@ void g_get_current_time (GTimeVal *result)
|
|||||||
|
|
||||||
/* Running the main loop */
|
/* Running the main loop */
|
||||||
|
|
||||||
|
/* HOLDS: main_loop_lock */
|
||||||
static void
|
static void
|
||||||
g_main_dispatch (GTimeVal *current_time)
|
g_main_dispatch (GTimeVal *current_time)
|
||||||
{
|
{
|
||||||
@ -294,10 +352,20 @@ g_main_dispatch (GTimeVal *current_time)
|
|||||||
|
|
||||||
if (G_HOOK_IS_VALID (source))
|
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;
|
source->hook.flags |= G_HOOK_FLAG_IN_CALL;
|
||||||
need_destroy = !((GSourceFuncs *)source->hook.func)->dispatch (source->source_data,
|
|
||||||
current_time,
|
g_unlock (main_loop);
|
||||||
source->hook.data);
|
need_destroy = ! dispatch(source_data,
|
||||||
|
current_time,
|
||||||
|
hook_data);
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
|
source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
|
||||||
|
|
||||||
if (need_destroy)
|
if (need_destroy)
|
||||||
@ -320,10 +388,13 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
gint nready = 0;
|
gint nready = 0;
|
||||||
gint current_priority = 0;
|
gint current_priority = 0;
|
||||||
gint timeout;
|
gint timeout;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
g_return_val_if_fail (!block || dispatch, FALSE);
|
g_return_val_if_fail (!block || dispatch, FALSE);
|
||||||
|
|
||||||
g_get_current_time (¤t_time);
|
g_get_current_time (¤t_time);
|
||||||
|
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
/* If recursing, finish up current dispatch, before starting over */
|
/* If recursing, finish up current dispatch, before starting over */
|
||||||
if (pending_dispatches)
|
if (pending_dispatches)
|
||||||
@ -331,6 +402,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
if (dispatch)
|
if (dispatch)
|
||||||
g_main_dispatch (¤t_time);
|
g_main_dispatch (¤t_time);
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +434,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
if (!dispatch)
|
if (!dispatch)
|
||||||
{
|
{
|
||||||
g_hook_unref (&source_list, hook);
|
g_hook_unref (&source_list, hook);
|
||||||
|
g_unlock (main_loop);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -426,6 +499,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_hook_unref (&source_list, hook);
|
g_hook_unref (&source_list, hook);
|
||||||
|
g_unlock (main_loop);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,10 +516,12 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
{
|
{
|
||||||
pending_dispatches = g_slist_reverse (pending_dispatches);
|
pending_dispatches = g_slist_reverse (pending_dispatches);
|
||||||
g_main_dispatch (¤t_time);
|
g_main_dispatch (¤t_time);
|
||||||
return TRUE;
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return FALSE;
|
g_unlock (main_loop);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if any events are pending
|
/* See if any events are pending
|
||||||
@ -494,11 +570,7 @@ g_main_destroy (GMainLoop *loop)
|
|||||||
g_free (loop);
|
g_free (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GPollRec *poll_records = NULL;
|
/* HOLDS: main_loop_lock */
|
||||||
static GPollRec *poll_free_list = NULL;
|
|
||||||
static GMemChunk *poll_chunk;
|
|
||||||
static guint n_poll_records = 0;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
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 i;
|
||||||
gint npoll;
|
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;
|
pollrec = poll_records;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (pollrec && (!use_priority || priority >= pollrec->priority))
|
while (pollrec && (!use_priority || priority >= pollrec->priority))
|
||||||
@ -520,8 +603,20 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
poll_waiting = TRUE;
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
npoll = i;
|
npoll = i;
|
||||||
(*poll_func) (fd_array, npoll, timeout);
|
(*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;
|
pollrec = poll_records;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -538,13 +633,29 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
|||||||
void
|
void
|
||||||
g_main_poll_add (gint priority,
|
g_main_poll_add (gint priority,
|
||||||
GPollFD *fd)
|
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;
|
GPollRec *lastrec, *pollrec, *newrec;
|
||||||
|
|
||||||
if (!poll_chunk)
|
if (!poll_chunk)
|
||||||
poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
|
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->fd = fd;
|
||||||
newrec->priority = priority;
|
newrec->priority = priority;
|
||||||
|
|
||||||
@ -564,6 +675,8 @@ g_main_poll_add (gint priority,
|
|||||||
newrec->next = pollrec;
|
newrec->next = pollrec;
|
||||||
|
|
||||||
n_poll_records++;
|
n_poll_records++;
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -571,6 +684,8 @@ g_main_poll_remove (GPollFD *fd)
|
|||||||
{
|
{
|
||||||
GPollRec *pollrec, *lastrec;
|
GPollRec *pollrec, *lastrec;
|
||||||
|
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
lastrec = NULL;
|
lastrec = NULL;
|
||||||
pollrec = poll_records;
|
pollrec = poll_records;
|
||||||
|
|
||||||
@ -585,12 +700,15 @@ g_main_poll_remove (GPollFD *fd)
|
|||||||
|
|
||||||
pollrec->next = poll_free_list;
|
pollrec->next = poll_free_list;
|
||||||
poll_free_list = pollrec;
|
poll_free_list = pollrec;
|
||||||
|
|
||||||
|
n_poll_records--;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
lastrec = pollrec;
|
lastrec = pollrec;
|
||||||
pollrec = pollrec->next;
|
pollrec = pollrec->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_poll_records--;
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
89
glib/gmem.c
89
glib/gmem.c
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -48,8 +52,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
|
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
|
||||||
#define ENTER_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk++
|
#define ENTER_MEM_CHUNK_ROUTINE() \
|
||||||
#define LEAVE_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk--
|
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
|
#else
|
||||||
#define ENTER_MEM_CHUNK_ROUTINE()
|
#define ENTER_MEM_CHUNK_ROUTINE()
|
||||||
#define LEAVE_MEM_CHUNK_ROUTINE()
|
#define LEAVE_MEM_CHUNK_ROUTINE()
|
||||||
@ -117,13 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
|
|||||||
gchar *addr);
|
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;
|
static GRealMemChunk *mem_chunks = NULL;
|
||||||
|
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
static GMutex* mem_profile_lock;
|
||||||
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
|
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
|
||||||
static gulong allocated_mem = 0;
|
static gulong allocated_mem = 0;
|
||||||
static gulong freed_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 */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
|
|
||||||
|
|
||||||
@ -174,8 +188,9 @@ g_malloc (gulong size)
|
|||||||
*t = size;
|
*t = size;
|
||||||
|
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile_lock);
|
||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
if(!allocating_for_mem_chunk) {
|
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||||
# endif
|
# endif
|
||||||
if (size <= MEM_PROFILE_TABLE_SIZE - 1)
|
if (size <= MEM_PROFILE_TABLE_SIZE - 1)
|
||||||
allocations[size-1] += 1;
|
allocations[size-1] += 1;
|
||||||
@ -185,6 +200,7 @@ g_malloc (gulong size)
|
|||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
g_mutex_unlock (mem_profile_lock);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
|
|
||||||
@ -237,8 +253,9 @@ g_malloc0 (gulong size)
|
|||||||
*t = size;
|
*t = size;
|
||||||
|
|
||||||
# ifdef ENABLE_MEM_PROFILE
|
# ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile_lock);
|
||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
if(!allocating_for_mem_chunk) {
|
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||||
# endif
|
# endif
|
||||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||||
allocations[size-1] += 1;
|
allocations[size-1] += 1;
|
||||||
@ -248,8 +265,9 @@ g_malloc0 (gulong size)
|
|||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
g_mutex_unlock (mem_profile_lock);
|
||||||
# endif /* ENABLE_MEM_PROFILE */
|
# endif /* ENABLE_MEM_PROFILE */
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -286,7 +304,9 @@ g_realloc (gpointer mem,
|
|||||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile);
|
||||||
freed_mem += *t;
|
freed_mem += *t;
|
||||||
|
g_mutex_unlock (mem_profile);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
mem = t;
|
mem = t;
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
@ -321,8 +341,9 @@ g_realloc (gpointer mem,
|
|||||||
*t = size;
|
*t = size;
|
||||||
|
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile_lock);
|
||||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
if(!allocating_for_mem_chunk) {
|
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||||
#endif
|
#endif
|
||||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||||
allocations[size-1] += 1;
|
allocations[size-1] += 1;
|
||||||
@ -332,6 +353,7 @@ g_realloc (gpointer mem,
|
|||||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
g_mutex_unlock (mem_profile_lock);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
|
|
||||||
@ -352,8 +374,10 @@ g_free (gpointer mem)
|
|||||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||||
size = *t;
|
size = *t;
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile);
|
||||||
freed_mem += size;
|
freed_mem += size;
|
||||||
|
g_mutex_unlock (mem_profile);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
mem = t;
|
mem = t;
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
@ -380,19 +404,29 @@ g_mem_profile (void)
|
|||||||
{
|
{
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
gint i;
|
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++)
|
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,
|
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,
|
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
|
||||||
"%lu allocations of greater than %d bytes\n",
|
"%lu allocations of greater than %d bytes\n",
|
||||||
allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1);
|
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", allocated_mem);
|
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", freed_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", allocated_mem - 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 */
|
#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);
|
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->next = mem_chunks;
|
||||||
mem_chunk->prev = NULL;
|
mem_chunk->prev = NULL;
|
||||||
if (mem_chunks)
|
if (mem_chunks)
|
||||||
mem_chunks->prev = mem_chunk;
|
mem_chunks->prev = mem_chunk;
|
||||||
mem_chunks = mem_chunk;
|
mem_chunks = mem_chunk;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
|
|
||||||
LEAVE_MEM_CHUNK_ROUTINE();
|
LEAVE_MEM_CHUNK_ROUTINE();
|
||||||
|
|
||||||
@ -497,8 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
|
|||||||
if (rmem_chunk->prev)
|
if (rmem_chunk->prev)
|
||||||
rmem_chunk->prev->next = rmem_chunk->next;
|
rmem_chunk->prev->next = rmem_chunk->next;
|
||||||
|
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
if (rmem_chunk == mem_chunks)
|
if (rmem_chunk == mem_chunks)
|
||||||
mem_chunks = mem_chunks->next;
|
mem_chunks = mem_chunks->next;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
|
|
||||||
if (rmem_chunk->type == G_ALLOC_AND_FREE)
|
if (rmem_chunk->type == G_ALLOC_AND_FREE)
|
||||||
g_tree_destroy (rmem_chunk->mem_tree);
|
g_tree_destroy (rmem_chunk->mem_tree);
|
||||||
@ -826,21 +864,26 @@ g_mem_chunk_info (void)
|
|||||||
gint count;
|
gint count;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
mem_chunk = mem_chunks;
|
mem_chunk = mem_chunks;
|
||||||
while (mem_chunk)
|
while (mem_chunk)
|
||||||
{
|
{
|
||||||
count += 1;
|
count += 1;
|
||||||
mem_chunk = mem_chunk->next;
|
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_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count);
|
||||||
|
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
mem_chunk = mem_chunks;
|
mem_chunk = mem_chunks;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
|
|
||||||
while (mem_chunk)
|
while (mem_chunk)
|
||||||
{
|
{
|
||||||
g_mem_chunk_print ((GMemChunk*) mem_chunk);
|
g_mem_chunk_print ((GMemChunk*) mem_chunk);
|
||||||
mem_chunk = mem_chunk->next;
|
mem_chunk = mem_chunk->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -848,7 +891,9 @@ g_blow_chunks (void)
|
|||||||
{
|
{
|
||||||
GRealMemChunk *mem_chunk;
|
GRealMemChunk *mem_chunk;
|
||||||
|
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
mem_chunk = mem_chunks;
|
mem_chunk = mem_chunks;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
while (mem_chunk)
|
while (mem_chunk)
|
||||||
{
|
{
|
||||||
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
|
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
|
||||||
@ -940,3 +985,13 @@ g_allocator_free (GAllocator *allocator)
|
|||||||
|
|
||||||
g_free (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.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -31,7 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NATIVE_WIN32
|
#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
|
#undef write
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -67,6 +71,9 @@ struct _GLogHandler
|
|||||||
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
|
|
||||||
|
static GMutex* g_messages_lock = NULL;
|
||||||
|
|
||||||
const gchar *g_log_domain_glib = "GLib";
|
const gchar *g_log_domain_glib = "GLib";
|
||||||
static GLogDomain *g_log_domains = NULL;
|
static GLogDomain *g_log_domains = NULL;
|
||||||
static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
|
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 GWarningFunc glib_warning_func = NULL;
|
||||||
static GPrintFunc glib_message_func = NULL;
|
static GPrintFunc glib_message_func = NULL;
|
||||||
|
|
||||||
|
static GPrivate* g_log_depth = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
static inline GLogDomain*
|
static inline GLogDomain*
|
||||||
g_log_find_domain (const gchar *log_domain)
|
g_log_find_domain (const gchar *log_domain)
|
||||||
{
|
{
|
||||||
register GLogDomain *domain;
|
register GLogDomain *domain;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
domain = g_log_domains;
|
domain = g_log_domains;
|
||||||
while (domain)
|
while (domain)
|
||||||
{
|
{
|
||||||
if (strcmp (domain->log_domain, log_domain) == 0)
|
if (strcmp (domain->log_domain, log_domain) == 0)
|
||||||
return domain;
|
{
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
domain = domain->next;
|
domain = domain->next;
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +116,11 @@ g_log_domain_new (const gchar *log_domain)
|
|||||||
domain->log_domain = g_strdup (log_domain);
|
domain->log_domain = g_strdup (log_domain);
|
||||||
domain->fatal_mask = G_LOG_FATAL_MASK;
|
domain->fatal_mask = G_LOG_FATAL_MASK;
|
||||||
domain->handlers = NULL;
|
domain->handlers = NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
domain->next = g_log_domains;
|
domain->next = g_log_domains;
|
||||||
g_log_domains = domain;
|
g_log_domains = domain;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
@ -116,7 +133,9 @@ g_log_domain_check_free (GLogDomain *domain)
|
|||||||
{
|
{
|
||||||
register GLogDomain *last, *work;
|
register GLogDomain *last, *work;
|
||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
work = g_log_domains;
|
work = g_log_domains;
|
||||||
while (work)
|
while (work)
|
||||||
{
|
{
|
||||||
@ -131,7 +150,8 @@ g_log_domain_check_free (GLogDomain *domain)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
work = work->next;
|
work = work->next;
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask)
|
|||||||
/* remove bogus flag */
|
/* remove bogus flag */
|
||||||
fatal_mask &= ~G_LOG_FLAG_FATAL;
|
fatal_mask &= ~G_LOG_FLAG_FATAL;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_mask = g_log_always_fatal;
|
old_mask = g_log_always_fatal;
|
||||||
g_log_always_fatal = fatal_mask;
|
g_log_always_fatal = fatal_mask;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_mask;
|
return old_mask;
|
||||||
}
|
}
|
||||||
@ -223,7 +245,9 @@ g_log_set_handler (const gchar *log_domain,
|
|||||||
domain = g_log_domain_new (log_domain);
|
domain = g_log_domain_new (log_domain);
|
||||||
|
|
||||||
handler = g_new (GLogHandler, 1);
|
handler = g_new (GLogHandler, 1);
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
handler->id = ++handler_id;
|
handler->id = ++handler_id;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
handler->log_level = log_levels;
|
handler->log_level = log_levels;
|
||||||
handler->log_func = log_func;
|
handler->log_func = log_func;
|
||||||
handler->data = user_data;
|
handler->data = user_data;
|
||||||
@ -311,19 +335,25 @@ g_logv (const gchar *log_domain,
|
|||||||
test_level = 1 << i;
|
test_level = 1 << i;
|
||||||
if (log_level & test_level)
|
if (log_level & test_level)
|
||||||
{
|
{
|
||||||
static guint g_log_depth = 0;
|
guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
|
||||||
GLogDomain *domain;
|
GLogDomain *domain;
|
||||||
GLogFunc log_func;
|
GLogFunc log_func;
|
||||||
gpointer data = NULL;
|
gpointer data = NULL;
|
||||||
|
|
||||||
domain = g_log_find_domain (log_domain ? log_domain : "");
|
domain = g_log_find_domain (log_domain ? log_domain : "");
|
||||||
|
|
||||||
if (g_log_depth++)
|
if (depth)
|
||||||
test_level |= G_LOG_FLAG_RECURSION;
|
test_level |= G_LOG_FLAG_RECURSION;
|
||||||
|
|
||||||
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) &
|
depth++;
|
||||||
test_level) != 0)
|
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
|
||||||
test_level |= G_LOG_FLAG_FATAL;
|
|
||||||
|
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 = g_log_domain_get_handler (domain, test_level, &data);
|
||||||
log_func (log_domain, test_level, buffer, 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)
|
if (test_level & G_LOG_FLAG_FATAL)
|
||||||
abort ();
|
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;
|
gint fd;
|
||||||
#endif
|
#endif
|
||||||
gboolean in_recursion;
|
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;
|
in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
|
||||||
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
||||||
log_level &= G_LOG_LEVEL_MASK;
|
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;
|
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
|
||||||
#endif
|
#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)
|
switch (log_level)
|
||||||
{
|
{
|
||||||
case G_LOG_LEVEL_ERROR:
|
case G_LOG_LEVEL_ERROR:
|
||||||
if (!log_domain && glib_error_func)
|
if (!log_domain && local_glib_error_func)
|
||||||
{
|
{
|
||||||
/* compatibility code */
|
/* compatibility code */
|
||||||
glib_error_func (message);
|
local_glib_error_func (message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* use write(2) for output, in case we are out of memeory */
|
/* 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);
|
write (fd, "\n", 1);
|
||||||
break;
|
break;
|
||||||
case G_LOG_LEVEL_WARNING:
|
case G_LOG_LEVEL_WARNING:
|
||||||
if (!log_domain && glib_warning_func)
|
if (!log_domain && local_glib_warning_func)
|
||||||
{
|
{
|
||||||
/* compatibility code */
|
/* compatibility code */
|
||||||
glib_warning_func (message);
|
local_glib_warning_func (message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (log_domain)
|
if (log_domain)
|
||||||
@ -453,10 +493,10 @@ g_log_default_handler (const gchar *log_domain,
|
|||||||
write (fd, "\n", 1);
|
write (fd, "\n", 1);
|
||||||
break;
|
break;
|
||||||
case G_LOG_LEVEL_MESSAGE:
|
case G_LOG_LEVEL_MESSAGE:
|
||||||
if (!log_domain && glib_message_func)
|
if (!log_domain && local_glib_message_func)
|
||||||
{
|
{
|
||||||
/* compatibility code */
|
/* compatibility code */
|
||||||
glib_message_func (message);
|
local_glib_message_func (message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (log_domain)
|
if (log_domain)
|
||||||
@ -553,8 +593,10 @@ g_set_print_handler (GPrintFunc func)
|
|||||||
{
|
{
|
||||||
GPrintFunc old_print_func;
|
GPrintFunc old_print_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_print_func = glib_print_func;
|
old_print_func = glib_print_func;
|
||||||
glib_print_func = func;
|
glib_print_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_print_func;
|
return old_print_func;
|
||||||
}
|
}
|
||||||
@ -565,6 +607,7 @@ g_print (const gchar *format,
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *string;
|
gchar *string;
|
||||||
|
GPrintFunc local_glib_print_func;
|
||||||
|
|
||||||
g_return_if_fail (format != NULL);
|
g_return_if_fail (format != NULL);
|
||||||
|
|
||||||
@ -572,8 +615,12 @@ g_print (const gchar *format,
|
|||||||
string = g_strdup_vprintf (format, args);
|
string = g_strdup_vprintf (format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
if (glib_print_func)
|
g_mutex_lock (g_messages_lock);
|
||||||
glib_print_func (string);
|
local_glib_print_func = glib_print_func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
|
if (local_glib_print_func)
|
||||||
|
local_glib_print_func (string);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fputs (string, stdout);
|
fputs (string, stdout);
|
||||||
@ -587,8 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
|
|||||||
{
|
{
|
||||||
GPrintFunc old_printerr_func;
|
GPrintFunc old_printerr_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_printerr_func = glib_printerr_func;
|
old_printerr_func = glib_printerr_func;
|
||||||
glib_printerr_func = func;
|
glib_printerr_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_printerr_func;
|
return old_printerr_func;
|
||||||
}
|
}
|
||||||
@ -599,6 +648,7 @@ g_printerr (const gchar *format,
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *string;
|
gchar *string;
|
||||||
|
GPrintFunc local_glib_printerr_func;
|
||||||
|
|
||||||
g_return_if_fail (format != NULL);
|
g_return_if_fail (format != NULL);
|
||||||
|
|
||||||
@ -606,8 +656,12 @@ g_printerr (const gchar *format,
|
|||||||
string = g_strdup_vprintf (format, args);
|
string = g_strdup_vprintf (format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
if (glib_printerr_func)
|
g_mutex_lock (g_messages_lock);
|
||||||
glib_printerr_func (string);
|
local_glib_printerr_func = glib_printerr_func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
|
if (local_glib_printerr_func)
|
||||||
|
local_glib_printerr_func (string);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fputs (string, stderr);
|
fputs (string, stderr);
|
||||||
@ -622,9 +676,11 @@ g_set_error_handler (GErrorFunc func)
|
|||||||
{
|
{
|
||||||
GErrorFunc old_error_func;
|
GErrorFunc old_error_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_error_func = glib_error_func;
|
old_error_func = glib_error_func;
|
||||||
glib_error_func = func;
|
glib_error_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_error_func;
|
return old_error_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,8 +690,10 @@ g_set_warning_handler (GWarningFunc func)
|
|||||||
{
|
{
|
||||||
GWarningFunc old_warning_func;
|
GWarningFunc old_warning_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_warning_func = glib_warning_func;
|
old_warning_func = glib_warning_func;
|
||||||
glib_warning_func = func;
|
glib_warning_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_warning_func;
|
return old_warning_func;
|
||||||
}
|
}
|
||||||
@ -646,8 +704,17 @@ g_set_message_handler (GPrintFunc func)
|
|||||||
{
|
{
|
||||||
GPrintFunc old_message_func;
|
GPrintFunc old_message_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_message_func = glib_message_func;
|
old_message_func = glib_message_func;
|
||||||
glib_message_func = func;
|
glib_message_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_message_func;
|
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,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
/* node allocation
|
/* node allocation
|
||||||
@ -34,10 +39,12 @@ struct _GAllocator /* from gmem.c */
|
|||||||
GNode *free_nodes; /* implementation specific */
|
GNode *free_nodes; /* implementation specific */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(current_allocator);
|
||||||
static GAllocator *current_allocator = NULL;
|
static GAllocator *current_allocator = NULL;
|
||||||
|
|
||||||
void
|
/* HOLDS: current_allocator_lock */
|
||||||
g_node_push_allocator (GAllocator *allocator)
|
static void
|
||||||
|
g_node_validate_allocator (GAllocator *allocator)
|
||||||
{
|
{
|
||||||
g_return_if_fail (allocator != NULL);
|
g_return_if_fail (allocator != NULL);
|
||||||
g_return_if_fail (allocator->is_unused == TRUE);
|
g_return_if_fail (allocator->is_unused == TRUE);
|
||||||
@ -62,13 +69,22 @@ g_node_push_allocator (GAllocator *allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
allocator->is_unused = FALSE;
|
allocator->is_unused = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_node_push_allocator (GAllocator *allocator)
|
||||||
|
{
|
||||||
|
g_node_validate_allocator ( allocator );
|
||||||
|
g_lock (current_allocator);
|
||||||
allocator->last = current_allocator;
|
allocator->last = current_allocator;
|
||||||
current_allocator = allocator;
|
current_allocator = allocator;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_node_pop_allocator (void)
|
g_node_pop_allocator (void)
|
||||||
{
|
{
|
||||||
|
g_lock (current_allocator);
|
||||||
if (current_allocator)
|
if (current_allocator)
|
||||||
{
|
{
|
||||||
GAllocator *allocator;
|
GAllocator *allocator;
|
||||||
@ -78,6 +94,7 @@ g_node_pop_allocator (void)
|
|||||||
allocator->last = NULL;
|
allocator->last = NULL;
|
||||||
allocator->is_unused = TRUE;
|
allocator->is_unused = TRUE;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,9 +104,15 @@ g_node_new (gpointer data)
|
|||||||
{
|
{
|
||||||
GNode *node;
|
GNode *node;
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
if (!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)
|
if (!current_allocator->free_nodes)
|
||||||
node = g_chunk_new (GNode, current_allocator->mem_chunk);
|
node = g_chunk_new (GNode, current_allocator->mem_chunk);
|
||||||
else
|
else
|
||||||
@ -97,6 +120,7 @@ g_node_new (gpointer data)
|
|||||||
node = current_allocator->free_nodes;
|
node = current_allocator->free_nodes;
|
||||||
current_allocator->free_nodes = node->next;
|
current_allocator->free_nodes = node->next;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
|
|
||||||
node->data = data;
|
node->data = data;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
@ -122,9 +146,11 @@ g_nodes_free (GNode *node)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
parent->next = current_allocator->free_nodes;
|
parent->next = current_allocator->free_nodes;
|
||||||
current_allocator->free_nodes = node;
|
current_allocator->free_nodes = node;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
static const guint g_primes[] =
|
static const guint g_primes[] =
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
* License along with this library; if not, write to the Free
|
* License along with this library; if not, write to the Free
|
||||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#define __gscanner_c__
|
#define __gscanner_c__
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -30,10 +35,12 @@ struct _GAllocator /* from gmem.c */
|
|||||||
GSList *free_lists; /* implementation specific */
|
GSList *free_lists; /* implementation specific */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(current_allocator);
|
||||||
static GAllocator *current_allocator = NULL;
|
static GAllocator *current_allocator = NULL;
|
||||||
|
|
||||||
void
|
/* HOLDS: current_allocator_lock */
|
||||||
g_slist_push_allocator (GAllocator *allocator)
|
static void
|
||||||
|
g_slist_validate_allocator (GAllocator *allocator)
|
||||||
{
|
{
|
||||||
g_return_if_fail (allocator != NULL);
|
g_return_if_fail (allocator != NULL);
|
||||||
g_return_if_fail (allocator->is_unused == TRUE);
|
g_return_if_fail (allocator->is_unused == TRUE);
|
||||||
@ -58,13 +65,22 @@ g_slist_push_allocator (GAllocator *allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
allocator->is_unused = FALSE;
|
allocator->is_unused = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_slist_push_allocator (GAllocator *allocator)
|
||||||
|
{
|
||||||
|
g_slist_validate_allocator (allocator);
|
||||||
|
g_lock (current_allocator);
|
||||||
allocator->last = current_allocator;
|
allocator->last = current_allocator;
|
||||||
current_allocator = allocator;
|
current_allocator = allocator;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_slist_pop_allocator (void)
|
g_slist_pop_allocator (void)
|
||||||
{
|
{
|
||||||
|
g_lock (current_allocator);
|
||||||
if (current_allocator)
|
if (current_allocator)
|
||||||
{
|
{
|
||||||
GAllocator *allocator;
|
GAllocator *allocator;
|
||||||
@ -74,6 +90,7 @@ g_slist_pop_allocator (void)
|
|||||||
allocator->last = NULL;
|
allocator->last = NULL;
|
||||||
allocator->is_unused = TRUE;
|
allocator->is_unused = TRUE;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList*
|
GSList*
|
||||||
@ -81,9 +98,15 @@ g_slist_alloc (void)
|
|||||||
{
|
{
|
||||||
GSList *list;
|
GSList *list;
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
if (!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)
|
if (!current_allocator->free_lists)
|
||||||
{
|
{
|
||||||
list = g_chunk_new (GSList, current_allocator->mem_chunk);
|
list = g_chunk_new (GSList, current_allocator->mem_chunk);
|
||||||
@ -103,6 +126,8 @@ g_slist_alloc (void)
|
|||||||
current_allocator->free_lists = list->next;
|
current_allocator->free_lists = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
|
|
||||||
list->next = NULL;
|
list->next = NULL;
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@ -114,8 +139,10 @@ g_slist_free (GSList *list)
|
|||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = list->next;
|
list->data = list->next;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +152,10 @@ g_slist_free_1 (GSList *list)
|
|||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = NULL;
|
list->data = NULL;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -208,7 +212,8 @@ g_strtod (const gchar *nptr,
|
|||||||
gchar*
|
gchar*
|
||||||
g_strerror (gint errnum)
|
g_strerror (gint errnum)
|
||||||
{
|
{
|
||||||
static char msg[64];
|
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||||
|
char *msg;
|
||||||
|
|
||||||
#ifdef HAVE_STRERROR
|
#ifdef HAVE_STRERROR
|
||||||
return strerror (errnum);
|
return strerror (errnum);
|
||||||
@ -634,7 +639,14 @@ g_strerror (gint errnum)
|
|||||||
if ((errnum > 0) && (errnum <= sys_nerr))
|
if ((errnum > 0) && (errnum <= sys_nerr))
|
||||||
return sys_errlist [errnum];
|
return sys_errlist [errnum];
|
||||||
#endif /* NO_SYS_ERRLIST */
|
#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);
|
sprintf (msg, "unknown error (%d)", errnum);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
@ -642,7 +654,8 @@ g_strerror (gint errnum)
|
|||||||
gchar*
|
gchar*
|
||||||
g_strsignal (gint signum)
|
g_strsignal (gint signum)
|
||||||
{
|
{
|
||||||
static char msg[64];
|
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||||
|
char *msg;
|
||||||
|
|
||||||
#ifdef HAVE_STRSIGNAL
|
#ifdef HAVE_STRSIGNAL
|
||||||
extern char *strsignal (int sig);
|
extern char *strsignal (int sig);
|
||||||
@ -748,6 +761,13 @@ g_strsignal (gint signum)
|
|||||||
extern char *sys_siglist[];
|
extern char *sys_siglist[];
|
||||||
return sys_siglist [signum];
|
return sys_siglist [signum];
|
||||||
#endif /* NO_SYS_SIGLIST */
|
#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);
|
sprintf (msg, "unknown signal (%d)", signum);
|
||||||
return msg;
|
return msg;
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -43,7 +48,7 @@ struct _GRealString
|
|||||||
gint alloc;
|
gint alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(string_mem_chunk);
|
||||||
static GMemChunk *string_mem_chunk = NULL;
|
static GMemChunk *string_mem_chunk = NULL;
|
||||||
|
|
||||||
/* Hash Functions.
|
/* Hash Functions.
|
||||||
@ -202,12 +207,14 @@ g_string_sized_new (guint dfl_size)
|
|||||||
{
|
{
|
||||||
GRealString *string;
|
GRealString *string;
|
||||||
|
|
||||||
|
g_lock (string_mem_chunk);
|
||||||
if (!string_mem_chunk)
|
if (!string_mem_chunk)
|
||||||
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
|
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
|
||||||
sizeof (GRealString),
|
sizeof (GRealString),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
string = g_chunk_new (GRealString, string_mem_chunk);
|
string = g_chunk_new (GRealString, string_mem_chunk);
|
||||||
|
g_unlock (string_mem_chunk);
|
||||||
|
|
||||||
string->alloc = 0;
|
string->alloc = 0;
|
||||||
string->len = 0;
|
string->len = 0;
|
||||||
@ -241,7 +248,9 @@ g_string_free (GString *string,
|
|||||||
if (free_segment)
|
if (free_segment)
|
||||||
g_free (string->str);
|
g_free (string->str);
|
||||||
|
|
||||||
|
g_lock (string_mem_chunk);
|
||||||
g_mem_chunk_free (string_mem_chunk, string);
|
g_mem_chunk_free (string_mem_chunk, string);
|
||||||
|
g_unlock (string_mem_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
GString*
|
GString*
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
18
glib/gtree.c
18
glib/gtree.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#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 void g_tree_node_check (GTreeNode *node);
|
||||||
|
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_tree_global);
|
||||||
static GMemChunk *node_mem_chunk = NULL;
|
static GMemChunk *node_mem_chunk = NULL;
|
||||||
static GTreeNode *node_free_list = NULL;
|
static GTreeNode *node_free_list = NULL;
|
||||||
|
|
||||||
@ -88,6 +94,7 @@ g_tree_node_new (gpointer key,
|
|||||||
{
|
{
|
||||||
GTreeNode *node;
|
GTreeNode *node;
|
||||||
|
|
||||||
|
g_lock (g_tree_global);
|
||||||
if (node_free_list)
|
if (node_free_list)
|
||||||
{
|
{
|
||||||
node = node_free_list;
|
node = node_free_list;
|
||||||
@ -102,7 +109,8 @@ g_tree_node_new (gpointer key,
|
|||||||
G_ALLOC_ONLY);
|
G_ALLOC_ONLY);
|
||||||
|
|
||||||
node = g_chunk_new (GTreeNode, node_mem_chunk);
|
node = g_chunk_new (GTreeNode, node_mem_chunk);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_tree_global);
|
||||||
|
|
||||||
node->balance = 0;
|
node->balance = 0;
|
||||||
node->left = NULL;
|
node->left = NULL;
|
||||||
@ -120,9 +128,11 @@ g_tree_node_destroy (GTreeNode *node)
|
|||||||
{
|
{
|
||||||
g_tree_node_destroy (node->right);
|
g_tree_node_destroy (node->right);
|
||||||
g_tree_node_destroy (node->left);
|
g_tree_node_destroy (node->left);
|
||||||
|
g_lock (g_tree_global);
|
||||||
node->right = node_free_list;
|
node->right = node_free_list;
|
||||||
node_free_list = node;
|
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);
|
node = g_tree_node_restore_right_balance (new_root, old_balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (g_tree_global);
|
||||||
garbage->right = node_free_list;
|
garbage->right = node_free_list;
|
||||||
node_free_list = garbage;
|
node_free_list = garbage;
|
||||||
}
|
g_unlock (g_tree_global);
|
||||||
|
}
|
||||||
else if (cmp < 0)
|
else if (cmp < 0)
|
||||||
{
|
{
|
||||||
if (node->left)
|
if (node->left)
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe for the unix part, FIXME: make the win32 part MT safe as well.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -367,11 +371,14 @@ g_getenv (const gchar *variable)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_utils_global);
|
||||||
|
|
||||||
static gchar *g_tmp_dir = NULL;
|
static gchar *g_tmp_dir = NULL;
|
||||||
static gchar *g_user_name = NULL;
|
static gchar *g_user_name = NULL;
|
||||||
static gchar *g_real_name = NULL;
|
static gchar *g_real_name = NULL;
|
||||||
static gchar *g_home_dir = NULL;
|
static gchar *g_home_dir = NULL;
|
||||||
|
|
||||||
|
/* HOLDS: g_utils_global_lock */
|
||||||
static void
|
static void
|
||||||
g_get_any_init (void)
|
g_get_any_init (void)
|
||||||
{
|
{
|
||||||
@ -442,14 +449,16 @@ g_get_any_init (void)
|
|||||||
g_home_dir = NULL;
|
g_home_dir = NULL;
|
||||||
# endif /* !NATIVE_WIN32 */
|
# endif /* !NATIVE_WIN32 */
|
||||||
#endif /* !HAVE_PWD_H */
|
#endif /* !HAVE_PWD_H */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar*
|
gchar*
|
||||||
g_get_user_name (void)
|
g_get_user_name (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_user_name;
|
return g_user_name;
|
||||||
}
|
}
|
||||||
@ -457,9 +466,11 @@ g_get_user_name (void)
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_real_name (void)
|
g_get_real_name (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_real_name;
|
return g_real_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,8 +483,10 @@ g_get_real_name (void)
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_home_dir (void)
|
g_get_home_dir (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_home_dir;
|
return g_home_dir;
|
||||||
}
|
}
|
||||||
@ -488,8 +501,10 @@ g_get_home_dir (void)
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_tmp_dir (void)
|
g_get_tmp_dir (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_tmp_dir;
|
return g_tmp_dir;
|
||||||
}
|
}
|
||||||
@ -499,16 +514,25 @@ static gchar *g_prgname = NULL;
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_prgname (void)
|
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
|
void
|
||||||
g_set_prgname (const gchar *prgname)
|
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_prgname = g_strdup (prgname);
|
||||||
g_free (c);
|
g_free (c);
|
||||||
|
g_unlock (g_utils_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
|
44
glist.c
44
glist.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -31,9 +36,11 @@ struct _GAllocator /* from gmem.c */
|
|||||||
};
|
};
|
||||||
|
|
||||||
static GAllocator *current_allocator = NULL;
|
static GAllocator *current_allocator = NULL;
|
||||||
|
static G_LOCK_DEFINE(current_allocator);
|
||||||
|
|
||||||
void
|
/* HOLDS: current_allocator_lock */
|
||||||
g_list_push_allocator (GAllocator *allocator)
|
static void
|
||||||
|
g_list_validate_allocator (GAllocator *allocator)
|
||||||
{
|
{
|
||||||
g_return_if_fail (allocator != NULL);
|
g_return_if_fail (allocator != NULL);
|
||||||
g_return_if_fail (allocator->is_unused == TRUE);
|
g_return_if_fail (allocator->is_unused == TRUE);
|
||||||
@ -58,13 +65,22 @@ g_list_push_allocator (GAllocator *allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
allocator->is_unused = FALSE;
|
allocator->is_unused = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_list_push_allocator(GAllocator *allocator)
|
||||||
|
{
|
||||||
|
g_list_validate_allocator ( allocator );
|
||||||
|
g_lock (current_allocator);
|
||||||
allocator->last = current_allocator;
|
allocator->last = current_allocator;
|
||||||
current_allocator = allocator;
|
current_allocator = allocator;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_list_pop_allocator (void)
|
g_list_pop_allocator (void)
|
||||||
{
|
{
|
||||||
|
g_lock (current_allocator);
|
||||||
if (current_allocator)
|
if (current_allocator)
|
||||||
{
|
{
|
||||||
GAllocator *allocator;
|
GAllocator *allocator;
|
||||||
@ -74,6 +90,7 @@ g_list_pop_allocator (void)
|
|||||||
allocator->last = NULL;
|
allocator->last = NULL;
|
||||||
allocator->is_unused = TRUE;
|
allocator->is_unused = TRUE;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
GList*
|
GList*
|
||||||
@ -81,9 +98,15 @@ g_list_alloc (void)
|
|||||||
{
|
{
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
if (!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)
|
if (!current_allocator->free_lists)
|
||||||
{
|
{
|
||||||
list = g_chunk_new (GList, current_allocator->mem_chunk);
|
list = g_chunk_new (GList, current_allocator->mem_chunk);
|
||||||
@ -103,6 +126,7 @@ g_list_alloc (void)
|
|||||||
current_allocator->free_lists = list->next;
|
current_allocator->free_lists = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
list->next = NULL;
|
list->next = NULL;
|
||||||
list->prev = NULL;
|
list->prev = NULL;
|
||||||
|
|
||||||
@ -112,23 +136,31 @@ g_list_alloc (void)
|
|||||||
void
|
void
|
||||||
g_list_free (GList *list)
|
g_list_free (GList *list)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = list->next;
|
list->data = list->next;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_list_free_1 (GList *list)
|
g_list_free_1 (GList *list)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = NULL;
|
list->data = NULL;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GList*
|
GList*
|
||||||
|
158
gmain.c
158
gmain.c
@ -20,9 +20,14 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
@ -65,9 +70,12 @@ struct _GPollRec {
|
|||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
|
|
||||||
static void g_main_poll (gint timeout,
|
static void g_main_poll (gint timeout,
|
||||||
gboolean use_priority,
|
gboolean use_priority,
|
||||||
gint priority);
|
gint priority);
|
||||||
|
static void g_main_poll_add_unlocked (gint priority,
|
||||||
|
GPollFD *fd);
|
||||||
|
|
||||||
static gboolean g_timeout_prepare (gpointer source_data,
|
static gboolean g_timeout_prepare (gpointer source_data,
|
||||||
GTimeVal *current_time,
|
GTimeVal *current_time,
|
||||||
gint *timeout);
|
gint *timeout);
|
||||||
@ -90,6 +98,11 @@ static gboolean g_idle_dispatch (gpointer source_data,
|
|||||||
static GSList *pending_dispatches = NULL;
|
static GSList *pending_dispatches = NULL;
|
||||||
static GHookList source_list = { 0 };
|
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 = {
|
static GSourceFuncs timeout_funcs = {
|
||||||
g_timeout_prepare,
|
g_timeout_prepare,
|
||||||
g_timeout_check,
|
g_timeout_check,
|
||||||
@ -104,6 +117,17 @@ static GSourceFuncs idle_funcs = {
|
|||||||
(GDestroyNotify)g_free
|
(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
|
#ifdef HAVE_POLL
|
||||||
static GPollFunc poll_func = (GPollFunc)poll;
|
static GPollFunc poll_func = (GPollFunc)poll;
|
||||||
#else
|
#else
|
||||||
@ -205,8 +229,11 @@ g_source_add (gint priority,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify notify)
|
GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
|
guint return_val;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
if (!source_list.is_setup)
|
if (!source_list.is_setup)
|
||||||
g_hook_list_init (&source_list, sizeof(GSource));
|
g_hook_list_init (&source_list, sizeof(GSource));
|
||||||
|
|
||||||
@ -224,31 +251,55 @@ g_source_add (gint priority,
|
|||||||
if (can_recurse)
|
if (can_recurse)
|
||||||
source->hook.flags |= G_SOURCE_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
|
void
|
||||||
g_source_remove (guint tag)
|
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)
|
if (hook)
|
||||||
{
|
{
|
||||||
GSource *source = (GSource *)hook;
|
GSource *source = (GSource *)hook;
|
||||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||||
g_hook_destroy_link (&source_list, hook);
|
g_hook_destroy_link (&source_list, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_source_remove_by_user_data (gpointer user_data)
|
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)
|
if (hook)
|
||||||
{
|
{
|
||||||
GSource *source = (GSource *)hook;
|
GSource *source = (GSource *)hook;
|
||||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||||
g_hook_destroy_link (&source_list, hook);
|
g_hook_destroy_link (&source_list, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -262,7 +313,11 @@ g_source_find_source_data (GHook *hook,
|
|||||||
void
|
void
|
||||||
g_source_remove_by_source_data (gpointer source_data)
|
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);
|
g_source_find_source_data, source_data);
|
||||||
if (hook)
|
if (hook)
|
||||||
{
|
{
|
||||||
@ -270,6 +325,8 @@ g_source_remove_by_source_data (gpointer source_data)
|
|||||||
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
((GSourceFuncs *)source->hook.func)->destroy (source->source_data);
|
||||||
g_hook_destroy_link (&source_list, hook);
|
g_hook_destroy_link (&source_list, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_get_current_time (GTimeVal *result)
|
void g_get_current_time (GTimeVal *result)
|
||||||
@ -279,6 +336,7 @@ void g_get_current_time (GTimeVal *result)
|
|||||||
|
|
||||||
/* Running the main loop */
|
/* Running the main loop */
|
||||||
|
|
||||||
|
/* HOLDS: main_loop_lock */
|
||||||
static void
|
static void
|
||||||
g_main_dispatch (GTimeVal *current_time)
|
g_main_dispatch (GTimeVal *current_time)
|
||||||
{
|
{
|
||||||
@ -294,10 +352,20 @@ g_main_dispatch (GTimeVal *current_time)
|
|||||||
|
|
||||||
if (G_HOOK_IS_VALID (source))
|
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;
|
source->hook.flags |= G_HOOK_FLAG_IN_CALL;
|
||||||
need_destroy = !((GSourceFuncs *)source->hook.func)->dispatch (source->source_data,
|
|
||||||
current_time,
|
g_unlock (main_loop);
|
||||||
source->hook.data);
|
need_destroy = ! dispatch(source_data,
|
||||||
|
current_time,
|
||||||
|
hook_data);
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
|
source->hook.flags &= ~G_HOOK_FLAG_IN_CALL;
|
||||||
|
|
||||||
if (need_destroy)
|
if (need_destroy)
|
||||||
@ -320,10 +388,13 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
gint nready = 0;
|
gint nready = 0;
|
||||||
gint current_priority = 0;
|
gint current_priority = 0;
|
||||||
gint timeout;
|
gint timeout;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
g_return_val_if_fail (!block || dispatch, FALSE);
|
g_return_val_if_fail (!block || dispatch, FALSE);
|
||||||
|
|
||||||
g_get_current_time (¤t_time);
|
g_get_current_time (¤t_time);
|
||||||
|
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
/* If recursing, finish up current dispatch, before starting over */
|
/* If recursing, finish up current dispatch, before starting over */
|
||||||
if (pending_dispatches)
|
if (pending_dispatches)
|
||||||
@ -331,6 +402,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
if (dispatch)
|
if (dispatch)
|
||||||
g_main_dispatch (¤t_time);
|
g_main_dispatch (¤t_time);
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +434,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
if (!dispatch)
|
if (!dispatch)
|
||||||
{
|
{
|
||||||
g_hook_unref (&source_list, hook);
|
g_hook_unref (&source_list, hook);
|
||||||
|
g_unlock (main_loop);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -426,6 +499,7 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_hook_unref (&source_list, hook);
|
g_hook_unref (&source_list, hook);
|
||||||
|
g_unlock (main_loop);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,10 +516,12 @@ g_main_iterate (gboolean block, gboolean dispatch)
|
|||||||
{
|
{
|
||||||
pending_dispatches = g_slist_reverse (pending_dispatches);
|
pending_dispatches = g_slist_reverse (pending_dispatches);
|
||||||
g_main_dispatch (¤t_time);
|
g_main_dispatch (¤t_time);
|
||||||
return TRUE;
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return FALSE;
|
g_unlock (main_loop);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if any events are pending
|
/* See if any events are pending
|
||||||
@ -494,11 +570,7 @@ g_main_destroy (GMainLoop *loop)
|
|||||||
g_free (loop);
|
g_free (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GPollRec *poll_records = NULL;
|
/* HOLDS: main_loop_lock */
|
||||||
static GPollRec *poll_free_list = NULL;
|
|
||||||
static GMemChunk *poll_chunk;
|
|
||||||
static guint n_poll_records = 0;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
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 i;
|
||||||
gint npoll;
|
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;
|
pollrec = poll_records;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (pollrec && (!use_priority || priority >= pollrec->priority))
|
while (pollrec && (!use_priority || priority >= pollrec->priority))
|
||||||
@ -520,8 +603,20 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
poll_waiting = TRUE;
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
npoll = i;
|
npoll = i;
|
||||||
(*poll_func) (fd_array, npoll, timeout);
|
(*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;
|
pollrec = poll_records;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -538,13 +633,29 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority)
|
|||||||
void
|
void
|
||||||
g_main_poll_add (gint priority,
|
g_main_poll_add (gint priority,
|
||||||
GPollFD *fd)
|
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;
|
GPollRec *lastrec, *pollrec, *newrec;
|
||||||
|
|
||||||
if (!poll_chunk)
|
if (!poll_chunk)
|
||||||
poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY);
|
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->fd = fd;
|
||||||
newrec->priority = priority;
|
newrec->priority = priority;
|
||||||
|
|
||||||
@ -564,6 +675,8 @@ g_main_poll_add (gint priority,
|
|||||||
newrec->next = pollrec;
|
newrec->next = pollrec;
|
||||||
|
|
||||||
n_poll_records++;
|
n_poll_records++;
|
||||||
|
|
||||||
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -571,6 +684,8 @@ g_main_poll_remove (GPollFD *fd)
|
|||||||
{
|
{
|
||||||
GPollRec *pollrec, *lastrec;
|
GPollRec *pollrec, *lastrec;
|
||||||
|
|
||||||
|
g_lock (main_loop);
|
||||||
|
|
||||||
lastrec = NULL;
|
lastrec = NULL;
|
||||||
pollrec = poll_records;
|
pollrec = poll_records;
|
||||||
|
|
||||||
@ -585,12 +700,15 @@ g_main_poll_remove (GPollFD *fd)
|
|||||||
|
|
||||||
pollrec->next = poll_free_list;
|
pollrec->next = poll_free_list;
|
||||||
poll_free_list = pollrec;
|
poll_free_list = pollrec;
|
||||||
|
|
||||||
|
n_poll_records--;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
lastrec = pollrec;
|
lastrec = pollrec;
|
||||||
pollrec = pollrec->next;
|
pollrec = pollrec->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_poll_records--;
|
g_unlock (main_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
89
gmem.c
89
gmem.c
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -48,8 +52,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
|
#if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS)
|
||||||
#define ENTER_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk++
|
#define ENTER_MEM_CHUNK_ROUTINE() \
|
||||||
#define LEAVE_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk--
|
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
|
#else
|
||||||
#define ENTER_MEM_CHUNK_ROUTINE()
|
#define ENTER_MEM_CHUNK_ROUTINE()
|
||||||
#define LEAVE_MEM_CHUNK_ROUTINE()
|
#define LEAVE_MEM_CHUNK_ROUTINE()
|
||||||
@ -117,13 +125,19 @@ static gint g_mem_chunk_area_search (GMemArea *a,
|
|||||||
gchar *addr);
|
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;
|
static GRealMemChunk *mem_chunks = NULL;
|
||||||
|
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
static GMutex* mem_profile_lock;
|
||||||
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
|
static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 };
|
||||||
static gulong allocated_mem = 0;
|
static gulong allocated_mem = 0;
|
||||||
static gulong freed_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 */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
|
|
||||||
|
|
||||||
@ -174,8 +188,9 @@ g_malloc (gulong size)
|
|||||||
*t = size;
|
*t = size;
|
||||||
|
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile_lock);
|
||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
if(!allocating_for_mem_chunk) {
|
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||||
# endif
|
# endif
|
||||||
if (size <= MEM_PROFILE_TABLE_SIZE - 1)
|
if (size <= MEM_PROFILE_TABLE_SIZE - 1)
|
||||||
allocations[size-1] += 1;
|
allocations[size-1] += 1;
|
||||||
@ -185,6 +200,7 @@ g_malloc (gulong size)
|
|||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
g_mutex_unlock (mem_profile_lock);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
|
|
||||||
@ -237,8 +253,9 @@ g_malloc0 (gulong size)
|
|||||||
*t = size;
|
*t = size;
|
||||||
|
|
||||||
# ifdef ENABLE_MEM_PROFILE
|
# ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile_lock);
|
||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
if(!allocating_for_mem_chunk) {
|
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||||
# endif
|
# endif
|
||||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||||
allocations[size-1] += 1;
|
allocations[size-1] += 1;
|
||||||
@ -248,8 +265,9 @@ g_malloc0 (gulong size)
|
|||||||
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
# ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
g_mutex_unlock (mem_profile_lock);
|
||||||
# endif /* ENABLE_MEM_PROFILE */
|
# endif /* ENABLE_MEM_PROFILE */
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -286,7 +304,9 @@ g_realloc (gpointer mem,
|
|||||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile);
|
||||||
freed_mem += *t;
|
freed_mem += *t;
|
||||||
|
g_mutex_unlock (mem_profile);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
mem = t;
|
mem = t;
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
@ -321,8 +341,9 @@ g_realloc (gpointer mem,
|
|||||||
*t = size;
|
*t = size;
|
||||||
|
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile_lock);
|
||||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
if(!allocating_for_mem_chunk) {
|
if(!IS_IN_MEM_CHUNK_ROUTINE()) {
|
||||||
#endif
|
#endif
|
||||||
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
if (size <= (MEM_PROFILE_TABLE_SIZE - 1))
|
||||||
allocations[size-1] += 1;
|
allocations[size-1] += 1;
|
||||||
@ -332,6 +353,7 @@ g_realloc (gpointer mem,
|
|||||||
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
#ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
g_mutex_unlock (mem_profile_lock);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
|
|
||||||
@ -352,8 +374,10 @@ g_free (gpointer mem)
|
|||||||
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
|
||||||
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
|
||||||
size = *t;
|
size = *t;
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
|
g_mutex_lock (mem_profile);
|
||||||
freed_mem += size;
|
freed_mem += size;
|
||||||
|
g_mutex_unlock (mem_profile);
|
||||||
#endif /* ENABLE_MEM_PROFILE */
|
#endif /* ENABLE_MEM_PROFILE */
|
||||||
mem = t;
|
mem = t;
|
||||||
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
|
||||||
@ -380,19 +404,29 @@ g_mem_profile (void)
|
|||||||
{
|
{
|
||||||
#ifdef ENABLE_MEM_PROFILE
|
#ifdef ENABLE_MEM_PROFILE
|
||||||
gint i;
|
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++)
|
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,
|
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,
|
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
|
||||||
"%lu allocations of greater than %d bytes\n",
|
"%lu allocations of greater than %d bytes\n",
|
||||||
allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1);
|
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", allocated_mem);
|
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", freed_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", allocated_mem - 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 */
|
#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);
|
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->next = mem_chunks;
|
||||||
mem_chunk->prev = NULL;
|
mem_chunk->prev = NULL;
|
||||||
if (mem_chunks)
|
if (mem_chunks)
|
||||||
mem_chunks->prev = mem_chunk;
|
mem_chunks->prev = mem_chunk;
|
||||||
mem_chunks = mem_chunk;
|
mem_chunks = mem_chunk;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
|
|
||||||
LEAVE_MEM_CHUNK_ROUTINE();
|
LEAVE_MEM_CHUNK_ROUTINE();
|
||||||
|
|
||||||
@ -497,8 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk)
|
|||||||
if (rmem_chunk->prev)
|
if (rmem_chunk->prev)
|
||||||
rmem_chunk->prev->next = rmem_chunk->next;
|
rmem_chunk->prev->next = rmem_chunk->next;
|
||||||
|
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
if (rmem_chunk == mem_chunks)
|
if (rmem_chunk == mem_chunks)
|
||||||
mem_chunks = mem_chunks->next;
|
mem_chunks = mem_chunks->next;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
|
|
||||||
if (rmem_chunk->type == G_ALLOC_AND_FREE)
|
if (rmem_chunk->type == G_ALLOC_AND_FREE)
|
||||||
g_tree_destroy (rmem_chunk->mem_tree);
|
g_tree_destroy (rmem_chunk->mem_tree);
|
||||||
@ -826,21 +864,26 @@ g_mem_chunk_info (void)
|
|||||||
gint count;
|
gint count;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
mem_chunk = mem_chunks;
|
mem_chunk = mem_chunks;
|
||||||
while (mem_chunk)
|
while (mem_chunk)
|
||||||
{
|
{
|
||||||
count += 1;
|
count += 1;
|
||||||
mem_chunk = mem_chunk->next;
|
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_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count);
|
||||||
|
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
mem_chunk = mem_chunks;
|
mem_chunk = mem_chunks;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
|
|
||||||
while (mem_chunk)
|
while (mem_chunk)
|
||||||
{
|
{
|
||||||
g_mem_chunk_print ((GMemChunk*) mem_chunk);
|
g_mem_chunk_print ((GMemChunk*) mem_chunk);
|
||||||
mem_chunk = mem_chunk->next;
|
mem_chunk = mem_chunk->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -848,7 +891,9 @@ g_blow_chunks (void)
|
|||||||
{
|
{
|
||||||
GRealMemChunk *mem_chunk;
|
GRealMemChunk *mem_chunk;
|
||||||
|
|
||||||
|
g_mutex_lock (mem_chunks_lock);
|
||||||
mem_chunk = mem_chunks;
|
mem_chunk = mem_chunks;
|
||||||
|
g_mutex_unlock (mem_chunks_lock);
|
||||||
while (mem_chunk)
|
while (mem_chunk)
|
||||||
{
|
{
|
||||||
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
|
g_mem_chunk_clean ((GMemChunk*) mem_chunk);
|
||||||
@ -940,3 +985,13 @@ g_allocator_free (GAllocator *allocator)
|
|||||||
|
|
||||||
g_free (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.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -31,7 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NATIVE_WIN32
|
#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
|
#undef write
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -67,6 +71,9 @@ struct _GLogHandler
|
|||||||
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
|
|
||||||
|
static GMutex* g_messages_lock = NULL;
|
||||||
|
|
||||||
const gchar *g_log_domain_glib = "GLib";
|
const gchar *g_log_domain_glib = "GLib";
|
||||||
static GLogDomain *g_log_domains = NULL;
|
static GLogDomain *g_log_domains = NULL;
|
||||||
static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
|
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 GWarningFunc glib_warning_func = NULL;
|
||||||
static GPrintFunc glib_message_func = NULL;
|
static GPrintFunc glib_message_func = NULL;
|
||||||
|
|
||||||
|
static GPrivate* g_log_depth = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
static inline GLogDomain*
|
static inline GLogDomain*
|
||||||
g_log_find_domain (const gchar *log_domain)
|
g_log_find_domain (const gchar *log_domain)
|
||||||
{
|
{
|
||||||
register GLogDomain *domain;
|
register GLogDomain *domain;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
domain = g_log_domains;
|
domain = g_log_domains;
|
||||||
while (domain)
|
while (domain)
|
||||||
{
|
{
|
||||||
if (strcmp (domain->log_domain, log_domain) == 0)
|
if (strcmp (domain->log_domain, log_domain) == 0)
|
||||||
return domain;
|
{
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
domain = domain->next;
|
domain = domain->next;
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +116,11 @@ g_log_domain_new (const gchar *log_domain)
|
|||||||
domain->log_domain = g_strdup (log_domain);
|
domain->log_domain = g_strdup (log_domain);
|
||||||
domain->fatal_mask = G_LOG_FATAL_MASK;
|
domain->fatal_mask = G_LOG_FATAL_MASK;
|
||||||
domain->handlers = NULL;
|
domain->handlers = NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
domain->next = g_log_domains;
|
domain->next = g_log_domains;
|
||||||
g_log_domains = domain;
|
g_log_domains = domain;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
@ -116,7 +133,9 @@ g_log_domain_check_free (GLogDomain *domain)
|
|||||||
{
|
{
|
||||||
register GLogDomain *last, *work;
|
register GLogDomain *last, *work;
|
||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
work = g_log_domains;
|
work = g_log_domains;
|
||||||
while (work)
|
while (work)
|
||||||
{
|
{
|
||||||
@ -131,7 +150,8 @@ g_log_domain_check_free (GLogDomain *domain)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
work = work->next;
|
work = work->next;
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask)
|
|||||||
/* remove bogus flag */
|
/* remove bogus flag */
|
||||||
fatal_mask &= ~G_LOG_FLAG_FATAL;
|
fatal_mask &= ~G_LOG_FLAG_FATAL;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_mask = g_log_always_fatal;
|
old_mask = g_log_always_fatal;
|
||||||
g_log_always_fatal = fatal_mask;
|
g_log_always_fatal = fatal_mask;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_mask;
|
return old_mask;
|
||||||
}
|
}
|
||||||
@ -223,7 +245,9 @@ g_log_set_handler (const gchar *log_domain,
|
|||||||
domain = g_log_domain_new (log_domain);
|
domain = g_log_domain_new (log_domain);
|
||||||
|
|
||||||
handler = g_new (GLogHandler, 1);
|
handler = g_new (GLogHandler, 1);
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
handler->id = ++handler_id;
|
handler->id = ++handler_id;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
handler->log_level = log_levels;
|
handler->log_level = log_levels;
|
||||||
handler->log_func = log_func;
|
handler->log_func = log_func;
|
||||||
handler->data = user_data;
|
handler->data = user_data;
|
||||||
@ -311,19 +335,25 @@ g_logv (const gchar *log_domain,
|
|||||||
test_level = 1 << i;
|
test_level = 1 << i;
|
||||||
if (log_level & test_level)
|
if (log_level & test_level)
|
||||||
{
|
{
|
||||||
static guint g_log_depth = 0;
|
guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
|
||||||
GLogDomain *domain;
|
GLogDomain *domain;
|
||||||
GLogFunc log_func;
|
GLogFunc log_func;
|
||||||
gpointer data = NULL;
|
gpointer data = NULL;
|
||||||
|
|
||||||
domain = g_log_find_domain (log_domain ? log_domain : "");
|
domain = g_log_find_domain (log_domain ? log_domain : "");
|
||||||
|
|
||||||
if (g_log_depth++)
|
if (depth)
|
||||||
test_level |= G_LOG_FLAG_RECURSION;
|
test_level |= G_LOG_FLAG_RECURSION;
|
||||||
|
|
||||||
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) &
|
depth++;
|
||||||
test_level) != 0)
|
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
|
||||||
test_level |= G_LOG_FLAG_FATAL;
|
|
||||||
|
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 = g_log_domain_get_handler (domain, test_level, &data);
|
||||||
log_func (log_domain, test_level, buffer, 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)
|
if (test_level & G_LOG_FLAG_FATAL)
|
||||||
abort ();
|
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;
|
gint fd;
|
||||||
#endif
|
#endif
|
||||||
gboolean in_recursion;
|
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;
|
in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
|
||||||
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
||||||
log_level &= G_LOG_LEVEL_MASK;
|
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;
|
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
|
||||||
#endif
|
#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)
|
switch (log_level)
|
||||||
{
|
{
|
||||||
case G_LOG_LEVEL_ERROR:
|
case G_LOG_LEVEL_ERROR:
|
||||||
if (!log_domain && glib_error_func)
|
if (!log_domain && local_glib_error_func)
|
||||||
{
|
{
|
||||||
/* compatibility code */
|
/* compatibility code */
|
||||||
glib_error_func (message);
|
local_glib_error_func (message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* use write(2) for output, in case we are out of memeory */
|
/* 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);
|
write (fd, "\n", 1);
|
||||||
break;
|
break;
|
||||||
case G_LOG_LEVEL_WARNING:
|
case G_LOG_LEVEL_WARNING:
|
||||||
if (!log_domain && glib_warning_func)
|
if (!log_domain && local_glib_warning_func)
|
||||||
{
|
{
|
||||||
/* compatibility code */
|
/* compatibility code */
|
||||||
glib_warning_func (message);
|
local_glib_warning_func (message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (log_domain)
|
if (log_domain)
|
||||||
@ -453,10 +493,10 @@ g_log_default_handler (const gchar *log_domain,
|
|||||||
write (fd, "\n", 1);
|
write (fd, "\n", 1);
|
||||||
break;
|
break;
|
||||||
case G_LOG_LEVEL_MESSAGE:
|
case G_LOG_LEVEL_MESSAGE:
|
||||||
if (!log_domain && glib_message_func)
|
if (!log_domain && local_glib_message_func)
|
||||||
{
|
{
|
||||||
/* compatibility code */
|
/* compatibility code */
|
||||||
glib_message_func (message);
|
local_glib_message_func (message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (log_domain)
|
if (log_domain)
|
||||||
@ -553,8 +593,10 @@ g_set_print_handler (GPrintFunc func)
|
|||||||
{
|
{
|
||||||
GPrintFunc old_print_func;
|
GPrintFunc old_print_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_print_func = glib_print_func;
|
old_print_func = glib_print_func;
|
||||||
glib_print_func = func;
|
glib_print_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_print_func;
|
return old_print_func;
|
||||||
}
|
}
|
||||||
@ -565,6 +607,7 @@ g_print (const gchar *format,
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *string;
|
gchar *string;
|
||||||
|
GPrintFunc local_glib_print_func;
|
||||||
|
|
||||||
g_return_if_fail (format != NULL);
|
g_return_if_fail (format != NULL);
|
||||||
|
|
||||||
@ -572,8 +615,12 @@ g_print (const gchar *format,
|
|||||||
string = g_strdup_vprintf (format, args);
|
string = g_strdup_vprintf (format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
if (glib_print_func)
|
g_mutex_lock (g_messages_lock);
|
||||||
glib_print_func (string);
|
local_glib_print_func = glib_print_func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
|
if (local_glib_print_func)
|
||||||
|
local_glib_print_func (string);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fputs (string, stdout);
|
fputs (string, stdout);
|
||||||
@ -587,8 +634,10 @@ g_set_printerr_handler (GPrintFunc func)
|
|||||||
{
|
{
|
||||||
GPrintFunc old_printerr_func;
|
GPrintFunc old_printerr_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_printerr_func = glib_printerr_func;
|
old_printerr_func = glib_printerr_func;
|
||||||
glib_printerr_func = func;
|
glib_printerr_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_printerr_func;
|
return old_printerr_func;
|
||||||
}
|
}
|
||||||
@ -599,6 +648,7 @@ g_printerr (const gchar *format,
|
|||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *string;
|
gchar *string;
|
||||||
|
GPrintFunc local_glib_printerr_func;
|
||||||
|
|
||||||
g_return_if_fail (format != NULL);
|
g_return_if_fail (format != NULL);
|
||||||
|
|
||||||
@ -606,8 +656,12 @@ g_printerr (const gchar *format,
|
|||||||
string = g_strdup_vprintf (format, args);
|
string = g_strdup_vprintf (format, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
if (glib_printerr_func)
|
g_mutex_lock (g_messages_lock);
|
||||||
glib_printerr_func (string);
|
local_glib_printerr_func = glib_printerr_func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
|
if (local_glib_printerr_func)
|
||||||
|
local_glib_printerr_func (string);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fputs (string, stderr);
|
fputs (string, stderr);
|
||||||
@ -622,9 +676,11 @@ g_set_error_handler (GErrorFunc func)
|
|||||||
{
|
{
|
||||||
GErrorFunc old_error_func;
|
GErrorFunc old_error_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_error_func = glib_error_func;
|
old_error_func = glib_error_func;
|
||||||
glib_error_func = func;
|
glib_error_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_error_func;
|
return old_error_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,8 +690,10 @@ g_set_warning_handler (GWarningFunc func)
|
|||||||
{
|
{
|
||||||
GWarningFunc old_warning_func;
|
GWarningFunc old_warning_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_warning_func = glib_warning_func;
|
old_warning_func = glib_warning_func;
|
||||||
glib_warning_func = func;
|
glib_warning_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_warning_func;
|
return old_warning_func;
|
||||||
}
|
}
|
||||||
@ -646,8 +704,17 @@ g_set_message_handler (GPrintFunc func)
|
|||||||
{
|
{
|
||||||
GPrintFunc old_message_func;
|
GPrintFunc old_message_func;
|
||||||
|
|
||||||
|
g_mutex_lock (g_messages_lock);
|
||||||
old_message_func = glib_message_func;
|
old_message_func = glib_message_func;
|
||||||
glib_message_func = func;
|
glib_message_func = func;
|
||||||
|
g_mutex_unlock (g_messages_lock);
|
||||||
|
|
||||||
return old_message_func;
|
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>
|
Fri Nov 20 14:43:44 1998 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* gmodule.c (_g_module_build_path): added empty default imlementation
|
* gmodule.c (_g_module_build_path): added empty default imlementation
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
/* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */
|
/* 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,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <dl.h>
|
#include <dl.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "gmodule.h"
|
#include "gmodule.h"
|
||||||
#include "gmoduleconf.h"
|
#include "gmoduleconf.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -59,10 +64,11 @@ static inline GModule* g_module_find_by_name (const gchar *name);
|
|||||||
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
const char *g_log_domain_gmodule = "GModule";
|
static G_LOCK_DEFINE (g_module_global);
|
||||||
static GModule *modules = NULL;
|
const char *g_log_domain_gmodule = "GModule";
|
||||||
static GModule *main_module = NULL;
|
static GModule *modules = NULL;
|
||||||
static gchar *module_error = NULL;
|
static GModule *main_module = NULL;
|
||||||
|
static GStaticPrivate module_error_private = G_STATIC_PRIVATE_INIT;
|
||||||
|
|
||||||
|
|
||||||
/* --- inline functions --- */
|
/* --- inline functions --- */
|
||||||
@ -70,30 +76,45 @@ static inline GModule*
|
|||||||
g_module_find_by_handle (gpointer handle)
|
g_module_find_by_handle (gpointer handle)
|
||||||
{
|
{
|
||||||
GModule *module;
|
GModule *module;
|
||||||
|
GModule *retval = NULL;
|
||||||
|
|
||||||
|
g_lock (g_module_global);
|
||||||
if (main_module && main_module->handle == handle)
|
if (main_module && main_module->handle == handle)
|
||||||
return main_module;
|
retval = main_module;
|
||||||
|
else
|
||||||
for (module = modules; module; module = module->next)
|
for (module = modules; module; module = module->next)
|
||||||
if (handle == module->handle)
|
if (handle == module->handle)
|
||||||
return module;
|
{
|
||||||
return NULL;
|
retval = module;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_unlock (g_module_global);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GModule*
|
static inline GModule*
|
||||||
g_module_find_by_name (const gchar *name)
|
g_module_find_by_name (const gchar *name)
|
||||||
{
|
{
|
||||||
GModule *module;
|
GModule *module;
|
||||||
|
GModule *retval = NULL;
|
||||||
|
|
||||||
|
g_lock (g_module_global);
|
||||||
for (module = modules; module; module = module->next)
|
for (module = modules; module; module = module->next)
|
||||||
if (strcmp (name, module->file_name) == 0)
|
if (strcmp (name, module->file_name) == 0)
|
||||||
return module;
|
{
|
||||||
return NULL;
|
retval = module;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_unlock (g_module_global);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
g_module_set_error (const gchar *error)
|
g_module_set_error (const gchar *error)
|
||||||
{
|
{
|
||||||
|
gchar* module_error = g_static_private_get (&module_error_private);
|
||||||
if (module_error)
|
if (module_error)
|
||||||
g_free (module_error);
|
g_free (module_error);
|
||||||
if (error)
|
if (error)
|
||||||
@ -101,6 +122,7 @@ g_module_set_error (const gchar *error)
|
|||||||
else
|
else
|
||||||
module_error = NULL;
|
module_error = NULL;
|
||||||
errno = 0;
|
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);
|
CHECK_ERROR (NULL);
|
||||||
|
|
||||||
if (!file_name)
|
if (!file_name)
|
||||||
{
|
{
|
||||||
|
g_lock (g_module_global);
|
||||||
if (!main_module)
|
if (!main_module)
|
||||||
{
|
{
|
||||||
handle = _g_module_self ();
|
handle = _g_module_self ();
|
||||||
@ -190,7 +213,8 @@ g_module_open (const gchar *file_name,
|
|||||||
main_module->next = NULL;
|
main_module->next = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (g_module_global);
|
||||||
|
|
||||||
return main_module;
|
return main_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,8 +246,8 @@ g_module_open (const gchar *file_name,
|
|||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_error = module_error;
|
saved_error = g_module_error();
|
||||||
module_error = NULL;
|
g_static_private_set (&module_error_private, NULL, NULL);
|
||||||
g_module_set_error (NULL);
|
g_module_set_error (NULL);
|
||||||
|
|
||||||
module = g_new (GModule, 1);
|
module = g_new (GModule, 1);
|
||||||
@ -232,8 +256,10 @@ g_module_open (const gchar *file_name,
|
|||||||
module->ref_count = 1;
|
module->ref_count = 1;
|
||||||
module->is_resident = FALSE;
|
module->is_resident = FALSE;
|
||||||
module->unload = NULL;
|
module->unload = NULL;
|
||||||
|
g_lock (g_module_global);
|
||||||
module->next = modules;
|
module->next = modules;
|
||||||
modules = module;
|
modules = module;
|
||||||
|
g_unlock (g_module_global);
|
||||||
|
|
||||||
/* check initialization */
|
/* check initialization */
|
||||||
if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init))
|
if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init))
|
||||||
@ -286,6 +312,8 @@ g_module_close (GModule *module)
|
|||||||
GModule *node;
|
GModule *node;
|
||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
|
|
||||||
|
g_lock (g_module_global);
|
||||||
node = modules;
|
node = modules;
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
@ -301,6 +329,7 @@ g_module_close (GModule *module)
|
|||||||
node = last->next;
|
node = last->next;
|
||||||
}
|
}
|
||||||
module->next = NULL;
|
module->next = NULL;
|
||||||
|
g_unlock (g_module_global);
|
||||||
|
|
||||||
_g_module_close (module->handle, FALSE);
|
_g_module_close (module->handle, FALSE);
|
||||||
g_free (module->file_name);
|
g_free (module->file_name);
|
||||||
@ -308,7 +337,7 @@ g_module_close (GModule *module)
|
|||||||
g_free (module);
|
g_free (module);
|
||||||
}
|
}
|
||||||
|
|
||||||
return module_error == NULL;
|
return g_module_error() == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -322,7 +351,7 @@ g_module_make_resident (GModule *module)
|
|||||||
gchar*
|
gchar*
|
||||||
g_module_error (void)
|
g_module_error (void)
|
||||||
{
|
{
|
||||||
return module_error;
|
return g_static_private_get (&module_error_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -330,6 +359,7 @@ g_module_symbol (GModule *module,
|
|||||||
const gchar *symbol_name,
|
const gchar *symbol_name,
|
||||||
gpointer *symbol)
|
gpointer *symbol)
|
||||||
{
|
{
|
||||||
|
gchar *module_error;
|
||||||
if (symbol)
|
if (symbol)
|
||||||
*symbol = NULL;
|
*symbol = NULL;
|
||||||
CHECK_ERROR (FALSE);
|
CHECK_ERROR (FALSE);
|
||||||
@ -350,7 +380,7 @@ g_module_symbol (GModule *module,
|
|||||||
*symbol = _g_module_symbol (module->handle, symbol_name);
|
*symbol = _g_module_symbol (module->handle, symbol_name);
|
||||||
#endif /* !G_MODULE_NEED_USCORE */
|
#endif /* !G_MODULE_NEED_USCORE */
|
||||||
|
|
||||||
if (module_error)
|
if ((module_error = g_module_error()))
|
||||||
{
|
{
|
||||||
gchar *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,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
/* node allocation
|
/* node allocation
|
||||||
@ -34,10 +39,12 @@ struct _GAllocator /* from gmem.c */
|
|||||||
GNode *free_nodes; /* implementation specific */
|
GNode *free_nodes; /* implementation specific */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(current_allocator);
|
||||||
static GAllocator *current_allocator = NULL;
|
static GAllocator *current_allocator = NULL;
|
||||||
|
|
||||||
void
|
/* HOLDS: current_allocator_lock */
|
||||||
g_node_push_allocator (GAllocator *allocator)
|
static void
|
||||||
|
g_node_validate_allocator (GAllocator *allocator)
|
||||||
{
|
{
|
||||||
g_return_if_fail (allocator != NULL);
|
g_return_if_fail (allocator != NULL);
|
||||||
g_return_if_fail (allocator->is_unused == TRUE);
|
g_return_if_fail (allocator->is_unused == TRUE);
|
||||||
@ -62,13 +69,22 @@ g_node_push_allocator (GAllocator *allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
allocator->is_unused = FALSE;
|
allocator->is_unused = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_node_push_allocator (GAllocator *allocator)
|
||||||
|
{
|
||||||
|
g_node_validate_allocator ( allocator );
|
||||||
|
g_lock (current_allocator);
|
||||||
allocator->last = current_allocator;
|
allocator->last = current_allocator;
|
||||||
current_allocator = allocator;
|
current_allocator = allocator;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_node_pop_allocator (void)
|
g_node_pop_allocator (void)
|
||||||
{
|
{
|
||||||
|
g_lock (current_allocator);
|
||||||
if (current_allocator)
|
if (current_allocator)
|
||||||
{
|
{
|
||||||
GAllocator *allocator;
|
GAllocator *allocator;
|
||||||
@ -78,6 +94,7 @@ g_node_pop_allocator (void)
|
|||||||
allocator->last = NULL;
|
allocator->last = NULL;
|
||||||
allocator->is_unused = TRUE;
|
allocator->is_unused = TRUE;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,9 +104,15 @@ g_node_new (gpointer data)
|
|||||||
{
|
{
|
||||||
GNode *node;
|
GNode *node;
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
if (!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)
|
if (!current_allocator->free_nodes)
|
||||||
node = g_chunk_new (GNode, current_allocator->mem_chunk);
|
node = g_chunk_new (GNode, current_allocator->mem_chunk);
|
||||||
else
|
else
|
||||||
@ -97,6 +120,7 @@ g_node_new (gpointer data)
|
|||||||
node = current_allocator->free_nodes;
|
node = current_allocator->free_nodes;
|
||||||
current_allocator->free_nodes = node->next;
|
current_allocator->free_nodes = node->next;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
|
|
||||||
node->data = data;
|
node->data = data;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
@ -122,9 +146,11 @@ g_nodes_free (GNode *node)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
parent->next = current_allocator->free_nodes;
|
parent->next = current_allocator->free_nodes;
|
||||||
current_allocator->free_nodes = node;
|
current_allocator->free_nodes = node;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
static const guint g_primes[] =
|
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
|
* License along with this library; if not, write to the Free
|
||||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#define __gscanner_c__
|
#define __gscanner_c__
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
37
gslist.c
37
gslist.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -30,10 +35,12 @@ struct _GAllocator /* from gmem.c */
|
|||||||
GSList *free_lists; /* implementation specific */
|
GSList *free_lists; /* implementation specific */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(current_allocator);
|
||||||
static GAllocator *current_allocator = NULL;
|
static GAllocator *current_allocator = NULL;
|
||||||
|
|
||||||
void
|
/* HOLDS: current_allocator_lock */
|
||||||
g_slist_push_allocator (GAllocator *allocator)
|
static void
|
||||||
|
g_slist_validate_allocator (GAllocator *allocator)
|
||||||
{
|
{
|
||||||
g_return_if_fail (allocator != NULL);
|
g_return_if_fail (allocator != NULL);
|
||||||
g_return_if_fail (allocator->is_unused == TRUE);
|
g_return_if_fail (allocator->is_unused == TRUE);
|
||||||
@ -58,13 +65,22 @@ g_slist_push_allocator (GAllocator *allocator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
allocator->is_unused = FALSE;
|
allocator->is_unused = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_slist_push_allocator (GAllocator *allocator)
|
||||||
|
{
|
||||||
|
g_slist_validate_allocator (allocator);
|
||||||
|
g_lock (current_allocator);
|
||||||
allocator->last = current_allocator;
|
allocator->last = current_allocator;
|
||||||
current_allocator = allocator;
|
current_allocator = allocator;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_slist_pop_allocator (void)
|
g_slist_pop_allocator (void)
|
||||||
{
|
{
|
||||||
|
g_lock (current_allocator);
|
||||||
if (current_allocator)
|
if (current_allocator)
|
||||||
{
|
{
|
||||||
GAllocator *allocator;
|
GAllocator *allocator;
|
||||||
@ -74,6 +90,7 @@ g_slist_pop_allocator (void)
|
|||||||
allocator->last = NULL;
|
allocator->last = NULL;
|
||||||
allocator->is_unused = TRUE;
|
allocator->is_unused = TRUE;
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList*
|
GSList*
|
||||||
@ -81,9 +98,15 @@ g_slist_alloc (void)
|
|||||||
{
|
{
|
||||||
GSList *list;
|
GSList *list;
|
||||||
|
|
||||||
|
g_lock (current_allocator);
|
||||||
if (!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)
|
if (!current_allocator->free_lists)
|
||||||
{
|
{
|
||||||
list = g_chunk_new (GSList, current_allocator->mem_chunk);
|
list = g_chunk_new (GSList, current_allocator->mem_chunk);
|
||||||
@ -103,6 +126,8 @@ g_slist_alloc (void)
|
|||||||
current_allocator->free_lists = list->next;
|
current_allocator->free_lists = list->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_unlock (current_allocator);
|
||||||
|
|
||||||
list->next = NULL;
|
list->next = NULL;
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@ -114,8 +139,10 @@ g_slist_free (GSList *list)
|
|||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = list->next;
|
list->data = list->next;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +152,10 @@ g_slist_free_1 (GSList *list)
|
|||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
list->data = NULL;
|
list->data = NULL;
|
||||||
|
g_lock (current_allocator);
|
||||||
list->next = current_allocator->free_lists;
|
list->next = current_allocator->free_lists;
|
||||||
current_allocator->free_lists = list;
|
current_allocator->free_lists = list;
|
||||||
|
g_unlock (current_allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
gstrfuncs.c
26
gstrfuncs.c
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -208,7 +212,8 @@ g_strtod (const gchar *nptr,
|
|||||||
gchar*
|
gchar*
|
||||||
g_strerror (gint errnum)
|
g_strerror (gint errnum)
|
||||||
{
|
{
|
||||||
static char msg[64];
|
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||||
|
char *msg;
|
||||||
|
|
||||||
#ifdef HAVE_STRERROR
|
#ifdef HAVE_STRERROR
|
||||||
return strerror (errnum);
|
return strerror (errnum);
|
||||||
@ -634,7 +639,14 @@ g_strerror (gint errnum)
|
|||||||
if ((errnum > 0) && (errnum <= sys_nerr))
|
if ((errnum > 0) && (errnum <= sys_nerr))
|
||||||
return sys_errlist [errnum];
|
return sys_errlist [errnum];
|
||||||
#endif /* NO_SYS_ERRLIST */
|
#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);
|
sprintf (msg, "unknown error (%d)", errnum);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
@ -642,7 +654,8 @@ g_strerror (gint errnum)
|
|||||||
gchar*
|
gchar*
|
||||||
g_strsignal (gint signum)
|
g_strsignal (gint signum)
|
||||||
{
|
{
|
||||||
static char msg[64];
|
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
||||||
|
char *msg;
|
||||||
|
|
||||||
#ifdef HAVE_STRSIGNAL
|
#ifdef HAVE_STRSIGNAL
|
||||||
extern char *strsignal (int sig);
|
extern char *strsignal (int sig);
|
||||||
@ -748,6 +761,13 @@ g_strsignal (gint signum)
|
|||||||
extern char *sys_siglist[];
|
extern char *sys_siglist[];
|
||||||
return sys_siglist [signum];
|
return sys_siglist [signum];
|
||||||
#endif /* NO_SYS_SIGLIST */
|
#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);
|
sprintf (msg, "unknown signal (%d)", signum);
|
||||||
return msg;
|
return msg;
|
||||||
|
11
gstring.c
11
gstring.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -43,7 +48,7 @@ struct _GRealString
|
|||||||
gint alloc;
|
gint alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(string_mem_chunk);
|
||||||
static GMemChunk *string_mem_chunk = NULL;
|
static GMemChunk *string_mem_chunk = NULL;
|
||||||
|
|
||||||
/* Hash Functions.
|
/* Hash Functions.
|
||||||
@ -202,12 +207,14 @@ g_string_sized_new (guint dfl_size)
|
|||||||
{
|
{
|
||||||
GRealString *string;
|
GRealString *string;
|
||||||
|
|
||||||
|
g_lock (string_mem_chunk);
|
||||||
if (!string_mem_chunk)
|
if (!string_mem_chunk)
|
||||||
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
|
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
|
||||||
sizeof (GRealString),
|
sizeof (GRealString),
|
||||||
1024, G_ALLOC_AND_FREE);
|
1024, G_ALLOC_AND_FREE);
|
||||||
|
|
||||||
string = g_chunk_new (GRealString, string_mem_chunk);
|
string = g_chunk_new (GRealString, string_mem_chunk);
|
||||||
|
g_unlock (string_mem_chunk);
|
||||||
|
|
||||||
string->alloc = 0;
|
string->alloc = 0;
|
||||||
string->len = 0;
|
string->len = 0;
|
||||||
@ -241,7 +248,9 @@ g_string_free (GString *string,
|
|||||||
if (free_segment)
|
if (free_segment)
|
||||||
g_free (string->str);
|
g_free (string->str);
|
||||||
|
|
||||||
|
g_lock (string_mem_chunk);
|
||||||
g_mem_chunk_free (string_mem_chunk, string);
|
g_mem_chunk_free (string_mem_chunk, string);
|
||||||
|
g_unlock (string_mem_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
GString*
|
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.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
18
gtree.c
18
gtree.c
@ -16,6 +16,11 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe
|
||||||
|
*/
|
||||||
|
|
||||||
#include "glib.h"
|
#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 void g_tree_node_check (GTreeNode *node);
|
||||||
|
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_tree_global);
|
||||||
static GMemChunk *node_mem_chunk = NULL;
|
static GMemChunk *node_mem_chunk = NULL;
|
||||||
static GTreeNode *node_free_list = NULL;
|
static GTreeNode *node_free_list = NULL;
|
||||||
|
|
||||||
@ -88,6 +94,7 @@ g_tree_node_new (gpointer key,
|
|||||||
{
|
{
|
||||||
GTreeNode *node;
|
GTreeNode *node;
|
||||||
|
|
||||||
|
g_lock (g_tree_global);
|
||||||
if (node_free_list)
|
if (node_free_list)
|
||||||
{
|
{
|
||||||
node = node_free_list;
|
node = node_free_list;
|
||||||
@ -102,7 +109,8 @@ g_tree_node_new (gpointer key,
|
|||||||
G_ALLOC_ONLY);
|
G_ALLOC_ONLY);
|
||||||
|
|
||||||
node = g_chunk_new (GTreeNode, node_mem_chunk);
|
node = g_chunk_new (GTreeNode, node_mem_chunk);
|
||||||
}
|
}
|
||||||
|
g_unlock (g_tree_global);
|
||||||
|
|
||||||
node->balance = 0;
|
node->balance = 0;
|
||||||
node->left = NULL;
|
node->left = NULL;
|
||||||
@ -120,9 +128,11 @@ g_tree_node_destroy (GTreeNode *node)
|
|||||||
{
|
{
|
||||||
g_tree_node_destroy (node->right);
|
g_tree_node_destroy (node->right);
|
||||||
g_tree_node_destroy (node->left);
|
g_tree_node_destroy (node->left);
|
||||||
|
g_lock (g_tree_global);
|
||||||
node->right = node_free_list;
|
node->right = node_free_list;
|
||||||
node_free_list = node;
|
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);
|
node = g_tree_node_restore_right_balance (new_root, old_balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_lock (g_tree_global);
|
||||||
garbage->right = node_free_list;
|
garbage->right = node_free_list;
|
||||||
node_free_list = garbage;
|
node_free_list = garbage;
|
||||||
}
|
g_unlock (g_tree_global);
|
||||||
|
}
|
||||||
else if (cmp < 0)
|
else if (cmp < 0)
|
||||||
{
|
{
|
||||||
if (node->left)
|
if (node->left)
|
||||||
|
34
gutils.c
34
gutils.c
@ -17,6 +17,10 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MT safe for the unix part, FIXME: make the win32 part MT safe as well.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@ -367,11 +371,14 @@ g_getenv (const gchar *variable)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static G_LOCK_DEFINE(g_utils_global);
|
||||||
|
|
||||||
static gchar *g_tmp_dir = NULL;
|
static gchar *g_tmp_dir = NULL;
|
||||||
static gchar *g_user_name = NULL;
|
static gchar *g_user_name = NULL;
|
||||||
static gchar *g_real_name = NULL;
|
static gchar *g_real_name = NULL;
|
||||||
static gchar *g_home_dir = NULL;
|
static gchar *g_home_dir = NULL;
|
||||||
|
|
||||||
|
/* HOLDS: g_utils_global_lock */
|
||||||
static void
|
static void
|
||||||
g_get_any_init (void)
|
g_get_any_init (void)
|
||||||
{
|
{
|
||||||
@ -442,14 +449,16 @@ g_get_any_init (void)
|
|||||||
g_home_dir = NULL;
|
g_home_dir = NULL;
|
||||||
# endif /* !NATIVE_WIN32 */
|
# endif /* !NATIVE_WIN32 */
|
||||||
#endif /* !HAVE_PWD_H */
|
#endif /* !HAVE_PWD_H */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar*
|
gchar*
|
||||||
g_get_user_name (void)
|
g_get_user_name (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_user_name;
|
return g_user_name;
|
||||||
}
|
}
|
||||||
@ -457,9 +466,11 @@ g_get_user_name (void)
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_real_name (void)
|
g_get_real_name (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_real_name;
|
return g_real_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,8 +483,10 @@ g_get_real_name (void)
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_home_dir (void)
|
g_get_home_dir (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_home_dir;
|
return g_home_dir;
|
||||||
}
|
}
|
||||||
@ -488,8 +501,10 @@ g_get_home_dir (void)
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_tmp_dir (void)
|
g_get_tmp_dir (void)
|
||||||
{
|
{
|
||||||
|
g_lock (g_utils_global);
|
||||||
if (!g_tmp_dir)
|
if (!g_tmp_dir)
|
||||||
g_get_any_init ();
|
g_get_any_init ();
|
||||||
|
g_unlock (g_utils_global);
|
||||||
|
|
||||||
return g_tmp_dir;
|
return g_tmp_dir;
|
||||||
}
|
}
|
||||||
@ -499,16 +514,25 @@ static gchar *g_prgname = NULL;
|
|||||||
gchar*
|
gchar*
|
||||||
g_get_prgname (void)
|
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
|
void
|
||||||
g_set_prgname (const gchar *prgname)
|
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_prgname = g_strdup (prgname);
|
||||||
g_free (c);
|
g_free (c);
|
||||||
|
g_unlock (g_utils_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
|
Loading…
Reference in New Issue
Block a user