* atexit in modules
@ 2008-11-13 5:59 Mike Gran
2008-11-13 19:26 ` Ludovic Courtès
0 siblings, 1 reply; 7+ messages in thread
From: Mike Gran @ 2008-11-13 5:59 UTC (permalink / raw)
To: Guile User
I have a C library that I wrapped as gsubrs that get put into a Guile module. The C library wants a library_init() function called when it is initialized and a library_end() function called when it taken down.
(for the curious, it is specifically mysql_library_init() and mysql_library_end().)
The library_init() call is easy because it can be called automatically in the initialization function called by (load-extension "libfoo.so" "foo_init").
Since libraries are never unloaded, I guess I can wait until the program exit to call library_end().
I read this thread
http://thread.gmane.org/gmane.lisp.guile.user/6430/focus=6443
This suggests dynamic-wind is the way to go, but, I don't think it would work in my case because I want to keep this in a Guile wrapper module that gets loaded with use-module.
I've got one crazy idea. I could create a new special SMOB type which calls library_end() as part of the SMOB's free function. When the Guile library is loaded, it will define a single variable of that type in the module's environment.
But then I started think about what happens if the module is used in multiple threads, and it made my head hurt.
Any better ideas?
-Mike Gran
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: atexit in modules
2008-11-13 5:59 atexit in modules Mike Gran
@ 2008-11-13 19:26 ` Ludovic Courtès
2008-11-13 19:59 ` Mike Gran
0 siblings, 1 reply; 7+ messages in thread
From: Ludovic Courtès @ 2008-11-13 19:26 UTC (permalink / raw)
To: guile-user
Hello,
Mike Gran <spk121@yahoo.com> writes:
> I have a C library that I wrapped as gsubrs that get put into a Guile
> module. The C library wants a library_init() function called when it
> is initialized and a library_end() function called when it taken down.
>
> (for the curious, it is specifically mysql_library_init() and
> mysql_library_end().)
>
> The library_init() call is easy because it can be called automatically
> in the initialization function called by (load-extension "libfoo.so"
> "foo_init").
In theory, the Right Way(tm) would be to register a finalizer for the
module that does `load-extension'. That can be done using a guardian,
but the guardian the needs to be called once in a while, e.g., in
`after-gc-hook' and `exit-hook'.
> Since libraries are never unloaded, I guess I can wait until the
> program exit to call library_end().
Well, yes. :-)
Then `exit-hook' should do the job, no?
> I've got one crazy idea. I could create a new special SMOB type which
> calls library_end() as part of the SMOB's free function. When the
> Guile library is loaded, it will define a single variable of that type
> in the module's environment.
The guardian suggestion above achieves that, but slightly more
elegantly. :-)
Thanks,
Ludo'.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: atexit in modules
2008-11-13 19:26 ` Ludovic Courtès
@ 2008-11-13 19:59 ` Mike Gran
2008-11-14 2:27 ` Mike Gran
0 siblings, 1 reply; 7+ messages in thread
From: Mike Gran @ 2008-11-13 19:59 UTC (permalink / raw)
To: guile-user
----- Original Message ----
> From: Ludovic Courtès ludo@gnu.org
> In theory, the Right Way(tm) would be to register a finalizer for the
> module that does `load-extension'. That can be done using a guardian,
> but the guardian the needs to be called once in a while, e.g., in
> `after-gc-hook' and `exit-hook'.
OK. I see in the manual there is a section on guardians and a mention of after-gc-hook in garbage-collection section. Cool.
Exit-hook is underdocumented. The one thread suggested that exit-hook is only called when using the REPL. Is that (still) true?
-Mike Gran
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: atexit in modules
2008-11-13 19:59 ` Mike Gran
@ 2008-11-14 2:27 ` Mike Gran
2008-11-16 0:27 ` Neil Jerram
0 siblings, 1 reply; 7+ messages in thread
From: Mike Gran @ 2008-11-14 2:27 UTC (permalink / raw)
To: guile-user
> ----- Original Message ----
> > From: Ludovic Courtès ludo@gnu.org
>
> > In theory, the Right Way(tm) would be to register a finalizer for the
> > module that does `load-extension'. That can be done using a guardian,
> > but the guardian the needs to be called once in a while, e.g., in
> > `after-gc-hook' and `exit-hook'.
>
> OK. I see in the manual there is a section on guardians and a mention of
> after-gc-hook in garbage-collection section. Cool.
>
> Exit-hook is underdocumented. The one thread suggested that exit-hook is only
> called when using the REPL. Is that (still) true?
Continuing...
Source diving tells me that exit-hook is a REPL-only feature.
So I'm back to the idea of creating a module-level variable that exists while the module is in memory, and then calling library_end() when that variable is GC'd. But I can make it more schemey by using guardians and after-gc-hook as you suggested.
Thanks,
Mike Gran
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: atexit in modules
2008-11-14 2:27 ` Mike Gran
@ 2008-11-16 0:27 ` Neil Jerram
2008-11-16 3:26 ` Mike Gran
0 siblings, 1 reply; 7+ messages in thread
From: Neil Jerram @ 2008-11-16 0:27 UTC (permalink / raw)
To: Mike Gran; +Cc: guile-user
2008/11/14 Mike Gran <spk121@yahoo.com>:
>
> So I'm back to the idea of creating a module-level variable that exists while the module is in memory, and then calling library_end() when that variable is GC'd. But I can make it more schemey by using guardians and after-gc-hook as you suggested.
But are modules ever unloaded? I thought not.
Neil
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: atexit in modules
2008-11-16 0:27 ` Neil Jerram
@ 2008-11-16 3:26 ` Mike Gran
2008-11-17 0:00 ` Ludovic Courtès
0 siblings, 1 reply; 7+ messages in thread
From: Mike Gran @ 2008-11-16 3:26 UTC (permalink / raw)
To: guile-user
> 2008/11/14 Mike Gran :
> >
> > So I'm back to the idea of creating a module-level variable that exists while
> > the module is in memory, and then calling library_end() when that variable is
> > GC'd. But I can make it more schemey by using guardians and after-gc-hook as
> >you suggested.
>
> But are modules ever unloaded? I thought not.
Everything I said above is nonsense. I tried four things, and the last one works fine.
Here's a review. I had a scheme module that wrapped a C library that required calls to a library_init() and library_end() function pair that allocated and freed global data.
Idea 1 was to wrap as library_init() as a scheme function that gets called when the scheme module is loaded, and then wrap library_end() as a scheme function that gets called when the module is unloaded. But, modules are never unloaded.
Idea 2 was to wrap library_init() as above, and then wrap library_end() as a scheme function that gets called when Guile exits. But, there is no such hook as far as I know for non-REPL Guile scripts.
Idea 3 was some nonsense idea that I could catch a module variable as it was being garbage collected and use this as the trigger to call library_end(). Ignore everything I said about that.
Idea 4: So ultimately I went with this. The C function library_init() gets called in init_foo() in the call to (load-extension "libfoo.so" "init_foo"). The C function library_end() gets registered using the libc atexit() during the same call to init_foo(). That works fine.
-Mike Gran
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: atexit in modules
2008-11-16 3:26 ` Mike Gran
@ 2008-11-17 0:00 ` Ludovic Courtès
0 siblings, 0 replies; 7+ messages in thread
From: Ludovic Courtès @ 2008-11-17 0:00 UTC (permalink / raw)
To: guile-user
Hello,
Mike Gran <spk121@yahoo.com> writes:
> Idea 1 was to wrap as library_init() as a scheme function that gets
> called when the scheme module is loaded, and then wrap library_end()
> as a scheme function that gets called when the module is unloaded.
> But, modules are never unloaded.
Yeah, that detail was the fun part of my proposal. :-)
> Idea 4: So ultimately I went with this. The C function library_init()
> gets called in init_foo() in the call to (load-extension "libfoo.so"
> "init_foo"). The C function library_end() gets registered using the
> libc atexit() during the same call to init_foo(). That works fine.
Indeed, couldn't be any simpler.
Thanks,
Ludo'.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-11-17 0:00 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-13 5:59 atexit in modules Mike Gran
2008-11-13 19:26 ` Ludovic Courtès
2008-11-13 19:59 ` Mike Gran
2008-11-14 2:27 ` Mike Gran
2008-11-16 0:27 ` Neil Jerram
2008-11-16 3:26 ` Mike Gran
2008-11-17 0:00 ` Ludovic Courtès
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).