unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* 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).