Hi R-help users.. I mistakenly posted a now rejected bug report (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14855), but the subject still bugs me..! If I have a package called MyPackage with C code inside, then library or require(MyPackage) will call loadNamespace() which will look for and call: void R_init_MyPackage(DllInfo *info) At the end of the R session, the corresponding unload function is however *not* called. void R_unload_MyPackage(DllInfo *info) I use the two functions to call R_cholmod_start(CHM_CM) and cholmod_finish(CHM_CM) respectively, and I think this might leak memory if the latter is not called. Firstly, why is one called without the package maker having to think about it, while the other is not? Secondly, how do I make sure that the unload function is called -- using either .Last.lib or .onUnload to call unloadNamespace() seems like a bad idea, as unloadNamespace() is documented to call back to these hooks (the call cycle would have to by broken by other means)? Kind regards, Henrik Alsing Friberg
On 26/03/2012 6:24 AM, Henrik Alsing Friberg wrote:> Hi R-help users.. > > I mistakenly posted a now rejected bug report > (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14855), but the > subject still bugs me..! > > If I have a package called MyPackage with C code inside, then library > or require(MyPackage) will call loadNamespace() which will look for > and call: > void R_init_MyPackage(DllInfo *info) > > At the end of the R session, the corresponding unload function is > however *not* called. > void R_unload_MyPackage(DllInfo *info) > > I use the two functions to call R_cholmod_start(CHM_CM) and > cholmod_finish(CHM_CM) respectively, and I think this might leak > memory if the latter is not called. Firstly, why is one called without > the package maker having to think about it, while the other is not? > Secondly, how do I make sure that the unload function is called -- > using either .Last.lib or .onUnload to call unloadNamespace() seems > like a bad idea, as unloadNamespace() is documented to call back to > these hooks (the call cycle would have to by broken by other means)?You would normally use reg.finalizer() for this, or the C level equivalents (see the section on external pointers in Writing R Extensions). Duncan Murdoch
I experimented with this earlier, but it is indeed tricky business. Last I tried my registered finalizer addressed unmapped memory, because garbage collection happened after my package (and thus the clean-up stuff) was unloaded. This happened using the R_RegisterFinalizerEx function from C++ on some dummy SEXP object. Since cholmod_finish is an exported function from the Matrix package, it has to be called before the Matrix package is unloaded. I will try something like >> reg.finalizer(environment(Matrix), fun, onexit=TRUE) Thanks. On Mon, Mar 26, 2012 at 4:21 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:> On 26/03/2012 6:24 AM, Henrik Alsing Friberg wrote: >> >> Hi R-help users.. >> >> I mistakenly posted a now rejected bug report >> (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14855), but the >> subject still bugs me..! >> >> If I have a package called MyPackage with C code inside, then library >> or require(MyPackage) will call loadNamespace() which will look for >> and call: >> void R_init_MyPackage(DllInfo *info) >> >> At the end of the R session, the corresponding unload function is >> however *not* called. >> void R_unload_MyPackage(DllInfo *info) >> >> I use the two functions to call R_cholmod_start(CHM_CM) and >> cholmod_finish(CHM_CM) respectively, and I think this might leak >> memory if the latter is not called. Firstly, why is one called without >> the package maker having to think about it, while the other is not? >> Secondly, how do I make sure that the unload function is called -- >> using either .Last.lib or .onUnload to call unloadNamespace() seems >> like a bad idea, as unloadNamespace() is documented to call back to >> these hooks (the call cycle would have to by broken by other means)? > > > You would normally use reg.finalizer() for this, or the C level equivalents > (see the section on external pointers in Writing R Extensions). > > Duncan Murdoch
On 28/03/2012 10:25 AM, Henrik Alsing Friberg wrote:> I experimented with this earlier, but it is indeed tricky business. > Last I tried my registered finalizer addressed unmapped memory, > because garbage collection happened after my package (and thus the > clean-up stuff) was unloaded. This happened using the > R_RegisterFinalizerEx function from C++ on some dummy SEXP object. > > Since cholmod_finish is an exported function from the Matrix package, > it has to be called before the Matrix package is unloaded. I will try > something like > >> reg.finalizer(environment(Matrix), fun, onexit=TRUE)If you still have trouble, you might want to study RODBC, which has to close down database connections. Duncan Murdoch> Thanks. > > > On Mon, Mar 26, 2012 at 4:21 PM, Duncan Murdoch > <murdoch.duncan at gmail.com> wrote: > > On 26/03/2012 6:24 AM, Henrik Alsing Friberg wrote: > >> > >> Hi R-help users.. > >> > >> I mistakenly posted a now rejected bug report > >> (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14855), but the > >> subject still bugs me..! > >> > >> If I have a package called MyPackage with C code inside, then library > >> or require(MyPackage) will call loadNamespace() which will look for > >> and call: > >> void R_init_MyPackage(DllInfo *info) > >> > >> At the end of the R session, the corresponding unload function is > >> however *not* called. > >> void R_unload_MyPackage(DllInfo *info) > >> > >> I use the two functions to call R_cholmod_start(CHM_CM) and > >> cholmod_finish(CHM_CM) respectively, and I think this might leak > >> memory if the latter is not called. Firstly, why is one called without > >> the package maker having to think about it, while the other is not? > >> Secondly, how do I make sure that the unload function is called -- > >> using either .Last.lib or .onUnload to call unloadNamespace() seems > >> like a bad idea, as unloadNamespace() is documented to call back to > >> these hooks (the call cycle would have to by broken by other means)? > > > > > > You would normally use reg.finalizer() for this, or the C level equivalents > > (see the section on external pointers in Writing R Extensions). > > > > Duncan Murdoch