mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +02:00
Add interface to disable automatic finalization
* libguile/finalizers.h: * libguile/finalizers.c (run_finalizers_async_thunk): Call the new scm_run_finalizers helper. (scm_set_automatic_finalization_enabled, scm_run_finalizers): New functions. (scm_init_finalizers): Only set a finalizer notifier if automatic finalization is enabled. * doc/ref/libguile-smobs.texi (Garbage Collecting Smobs): Add discussion of concurrency. * doc/ref/api-smobs.texi (Smobs): Document new functions.
This commit is contained in:
parent
e0da53b4fe
commit
fa1a30726d
4 changed files with 101 additions and 6 deletions
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2013
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2013, 2014
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -60,6 +60,36 @@ memory is automatically reclaimed by the garbage collector when it is no
|
||||||
longer needed (@pxref{Memory Blocks, @code{scm_gc_malloc}}).
|
longer needed (@pxref{Memory Blocks, @code{scm_gc_malloc}}).
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
Smob free functions must be thread-safe. @xref{Garbage Collecting
|
||||||
|
Smobs}, for a discussion on finalizers and concurrency. If you are
|
||||||
|
embedding Guile in an application that is not thread-safe, and you
|
||||||
|
define smob types that need finalization, you might want to disable
|
||||||
|
automatic finalization, and arrange to call
|
||||||
|
@code{scm_manually_run_finalizers ()} yourself.
|
||||||
|
|
||||||
|
@deftypefn {C Function} int scm_set_automatic_finalization_enabled (int enabled_p)
|
||||||
|
Enable or disable automatic finalization. By default, Guile arranges to
|
||||||
|
invoke object finalizers automatically, in a separate thread if
|
||||||
|
possible. Passing a zero value for @var{enabled_p} will disable
|
||||||
|
automatic finalization for Guile as a whole. If you disable automatic
|
||||||
|
finalization, you will have to call @code{scm_run_finalizers ()}
|
||||||
|
periodically.
|
||||||
|
|
||||||
|
Unlike most other Guile functions, you can call
|
||||||
|
@code{scm_set_automatic_finalization_enabled} before Guile has been
|
||||||
|
initialized.
|
||||||
|
|
||||||
|
Return the previous status of automatic finalization.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {C Function} int scm_run_finalizers (void)
|
||||||
|
Invoke any pending finalizers. Returns the number of finalizers that
|
||||||
|
were invoked. This function should be called when automatic
|
||||||
|
finalization is disabled, though it may be called if it is enabled as
|
||||||
|
well.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
|
||||||
@cindex precise marking
|
@cindex precise marking
|
||||||
|
|
||||||
@deftypefn {C Function} void scm_set_smob_mark (scm_t_bits tc, SCM (*mark) (SCM obj))
|
@deftypefn {C Function} void scm_set_smob_mark (scm_t_bits tc, SCM (*mark) (SCM obj))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@c -*-texinfo-*-
|
@c -*-texinfo-*-
|
||||||
@c This is part of the GNU Guile Reference Manual.
|
@c This is part of the GNU Guile Reference Manual.
|
||||||
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013, 2014
|
||||||
@c Free Software Foundation, Inc.
|
@c Free Software Foundation, Inc.
|
||||||
@c See the file guile.texi for copying conditions.
|
@c See the file guile.texi for copying conditions.
|
||||||
|
|
||||||
|
@ -385,6 +385,27 @@ During the sweep phase, the garbage collector will clear the mark bits
|
||||||
on all live objects. The code which implements a smob need not do this
|
on all live objects. The code which implements a smob need not do this
|
||||||
itself.
|
itself.
|
||||||
|
|
||||||
|
@cindex finalizer
|
||||||
|
@cindex finalization
|
||||||
|
|
||||||
|
Note that the free function can be called in any context. In
|
||||||
|
particular, if your Guile is built with support for threads, the
|
||||||
|
finalizer may be called from any thread that is running Guile. In Guile
|
||||||
|
2.0, finalizers are invoked via ``asyncs'', which interleaves them with
|
||||||
|
running Scheme code; @pxref{System asyncs}. In Guile 2.2 there will be
|
||||||
|
a dedicated finalization thread, to ensure that the finalization doesn't
|
||||||
|
run within the critical section of any other thread known to Guile.
|
||||||
|
|
||||||
|
In either case, finalizers (free functions) run concurrently with the
|
||||||
|
main program, and so they need to be async-safe and thread-safe. If for
|
||||||
|
some reason this is impossible, perhaps because you are embedding Guile
|
||||||
|
in some application that is not itself thread-safe, you have a few
|
||||||
|
options. One is to use guardians instead of free functions, and arrange
|
||||||
|
to pump the guardians for finalizable objects. @xref{Guardians}, for
|
||||||
|
more information. The other option is to disable automatic finalization
|
||||||
|
entirely, and arrange to call @code{scm_run_finalizers ()} at
|
||||||
|
appropriate points. @xref{Smobs}, for more on these interfaces.
|
||||||
|
|
||||||
There is no way for smob code to be notified when collection is
|
There is no way for smob code to be notified when collection is
|
||||||
complete.
|
complete.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2012 Free Software Foundation, Inc.
|
/* Copyright (C) 2012, 2014 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int automatic_finalization_p = 1;
|
||||||
|
|
||||||
static size_t finalization_count;
|
static size_t finalization_count;
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,7 +132,7 @@ static SCM finalizer_async_cell;
|
||||||
static SCM
|
static SCM
|
||||||
run_finalizers_async_thunk (void)
|
run_finalizers_async_thunk (void)
|
||||||
{
|
{
|
||||||
finalization_count += GC_invoke_finalizers ();
|
scm_run_finalizers ();
|
||||||
return SCM_UNSPECIFIED;
|
return SCM_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +171,43 @@ GC_set_finalizer_notifier (void (*notifier) (void))
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
scm_set_automatic_finalization_enabled (int enabled_p)
|
||||||
|
{
|
||||||
|
int was_enabled_p = automatic_finalization_p;
|
||||||
|
|
||||||
|
if (enabled_p == was_enabled_p)
|
||||||
|
return was_enabled_p;
|
||||||
|
|
||||||
|
if (!scm_initialized_p)
|
||||||
|
{
|
||||||
|
automatic_finalization_p = enabled_p;
|
||||||
|
return was_enabled_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
GC_set_finalizer_notifier (enabled_p ? queue_finalizer_async : 0);
|
||||||
|
|
||||||
|
automatic_finalization_p = enabled_p;
|
||||||
|
|
||||||
|
return was_enabled_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
scm_run_finalizers (void)
|
||||||
|
{
|
||||||
|
int finalized = GC_invoke_finalizers ();
|
||||||
|
|
||||||
|
finalization_count += finalized;
|
||||||
|
|
||||||
|
return finalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_init_finalizers (void)
|
scm_init_finalizers (void)
|
||||||
{
|
{
|
||||||
|
@ -178,5 +217,7 @@ scm_init_finalizers (void)
|
||||||
scm_cons (scm_c_make_gsubr ("%run-finalizers", 0, 0, 0,
|
scm_cons (scm_c_make_gsubr ("%run-finalizers", 0, 0, 0,
|
||||||
run_finalizers_async_thunk),
|
run_finalizers_async_thunk),
|
||||||
SCM_BOOL_F);
|
SCM_BOOL_F);
|
||||||
|
|
||||||
|
if (automatic_finalization_p)
|
||||||
GC_set_finalizer_notifier (queue_finalizer_async);
|
GC_set_finalizer_notifier (queue_finalizer_async);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef SCM_FINALIZERS_H
|
#ifndef SCM_FINALIZERS_H
|
||||||
#define SCM_FINALIZERS_H
|
#define SCM_FINALIZERS_H
|
||||||
|
|
||||||
/* Copyright (C) 2012 Free Software Foundation, Inc.
|
/* Copyright (C) 2012, 2014 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -34,6 +34,9 @@ SCM_INTERNAL void scm_i_add_finalizer (void *obj, scm_t_finalizer_proc,
|
||||||
SCM_INTERNAL void scm_i_add_resuscitator (void *obj, scm_t_finalizer_proc,
|
SCM_INTERNAL void scm_i_add_resuscitator (void *obj, scm_t_finalizer_proc,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
SCM_API int scm_set_automatic_finalization_enabled (int enabled_p);
|
||||||
|
SCM_API int scm_run_finalizers (void);
|
||||||
|
|
||||||
SCM_INTERNAL void scm_init_finalizers (void);
|
SCM_INTERNAL void scm_init_finalizers (void);
|
||||||
|
|
||||||
#endif /* SCM_FINALIZERS_H */
|
#endif /* SCM_FINALIZERS_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue