From 7b327550e20967b0a8f89182bcf9a04543db3a0f Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sun, 19 Feb 2012 12:22:12 +0100 Subject: add scm_i_set_finalizer, scm_i_add_finalizer, scm_i_add_resuscitator * libguile/finalizers.h: * libguile/finalizers.c: New files. * libguile.h: * libguile/Makefile.am: Add to build. --- libguile.h | 3 +- libguile/Makefile.am | 4 +- libguile/finalizers.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ libguile/finalizers.h | 39 ++++++++++++++++ 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 libguile/finalizers.c create mode 100644 libguile/finalizers.h diff --git a/libguile.h b/libguile.h index 2c10d05e9..fefca435b 100644 --- a/libguile.h +++ b/libguile.h @@ -1,7 +1,7 @@ #ifndef SCM_LIBGUILE_H #define SCM_LIBGUILE_H -/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -49,6 +49,7 @@ extern "C" { #include "libguile/extensions.h" #include "libguile/feature.h" #include "libguile/filesys.h" +#include "libguile/finalizers.h" #include "libguile/fluids.h" #include "libguile/foreign.h" #include "libguile/fports.h" diff --git a/libguile/Makefile.am b/libguile/Makefile.am index c181b998f..be430bf83 100644 --- a/libguile/Makefile.am +++ b/libguile/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with Automake to create Makefile.in ## -## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. ## ## This file is part of GUILE. ## @@ -142,6 +142,7 @@ libguile_@GUILE_EFFECTIVE_VERSION@_la_SOURCES = \ extensions.c \ feature.c \ filesys.c \ + finalizers.c \ fluids.c \ foreign.c \ fports.c \ @@ -530,6 +531,7 @@ modinclude_HEADERS = \ expand.h \ extensions.h \ feature.h \ + finalizers.h \ filesys.h \ fluids.h \ foreign.h \ diff --git a/libguile/finalizers.c b/libguile/finalizers.c new file mode 100644 index 000000000..8b4178ffc --- /dev/null +++ b/libguile/finalizers.c @@ -0,0 +1,126 @@ +/* Copyright (C) 2012 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libguile/bdw-gc.h" +#include "libguile/_scm.h" +#include "libguile/finalizers.h" +#include "libguile/gc.h" +#include "libguile/threads.h" + + + +void +scm_i_set_finalizer (void *obj, scm_t_finalizer_proc proc, void *data) +{ + GC_finalization_proc prev; + GC_PTR prev_data; + GC_REGISTER_FINALIZER_NO_ORDER (obj, proc, data, &prev, &prev_data); +} + +struct scm_t_chained_finalizer +{ + int resuscitating_p; + scm_t_finalizer_proc proc; + void *data; + scm_t_finalizer_proc prev; + void *prev_data; +}; + +static void +chained_finalizer (void *obj, void *data) +{ + struct scm_t_chained_finalizer *chained_data = data; + if (chained_data->resuscitating_p) + { + if (chained_data->prev) + scm_i_set_finalizer (obj, chained_data->prev, chained_data->prev_data); + chained_data->proc (obj, chained_data->data); + } + else + { + chained_data->proc (obj, chained_data->data); + if (chained_data->prev) + chained_data->prev (obj, chained_data->prev_data); + } +} + +void +scm_i_add_resuscitator (void *obj, scm_t_finalizer_proc proc, void *data) +{ + struct scm_t_chained_finalizer *chained_data; + chained_data = scm_gc_malloc (sizeof (*chained_data), "chained finalizer"); + chained_data->resuscitating_p = 1; + chained_data->proc = proc; + chained_data->data = data; + GC_REGISTER_FINALIZER_NO_ORDER (obj, chained_finalizer, chained_data, + &chained_data->prev, + &chained_data->prev_data); +} + +static void +shuffle_resuscitators_to_front (struct scm_t_chained_finalizer *cd) +{ + while (cd->prev == chained_finalizer) + { + struct scm_t_chained_finalizer *prev = cd->prev_data; + scm_t_finalizer_proc proc = cd->proc; + void *data = cd->data; + + if (!prev->resuscitating_p) + break; + + cd->resuscitating_p = 1; + cd->proc = prev->proc; + cd->data = prev->data; + + prev->resuscitating_p = 0; + prev->proc = proc; + prev->data = data; + + cd = prev; + } +} + +void +scm_i_add_finalizer (void *obj, scm_t_finalizer_proc proc, void *data) +{ + struct scm_t_chained_finalizer *chained_data; + chained_data = scm_gc_malloc (sizeof (*chained_data), "chained finalizer"); + chained_data->resuscitating_p = 0; + chained_data->proc = proc; + chained_data->data = data; + GC_REGISTER_FINALIZER_NO_ORDER (obj, chained_finalizer, chained_data, + &chained_data->prev, + &chained_data->prev_data); + shuffle_resuscitators_to_front (chained_data); +} + + + + +void +scm_init_finalizers (void) +{ +} diff --git a/libguile/finalizers.h b/libguile/finalizers.h new file mode 100644 index 000000000..bad96e145 --- /dev/null +++ b/libguile/finalizers.h @@ -0,0 +1,39 @@ +#ifndef SCM_FINALIZERS_H +#define SCM_FINALIZERS_H + +/* Copyright (C) 2012 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + + +#include "libguile/__scm.h" + + + +typedef void (*scm_t_finalizer_proc) (void *obj, void *data); + +SCM_INTERNAL void scm_i_set_finalizer (void *obj, scm_t_finalizer_proc, + void *data); +SCM_INTERNAL void scm_i_add_finalizer (void *obj, scm_t_finalizer_proc, + void *data); +SCM_INTERNAL void scm_i_add_resuscitator (void *obj, scm_t_finalizer_proc, + void *data); + +SCM_INTERNAL void scm_init_finalizers (void); + +#endif /* SCM_FINALIZERS_H */ -- cgit v1.2.3