Skip to content

run the module body only once per dll - #1528

Open
kevinushey wants to merge 1 commit into
bugfix/module-boot-exceptionsfrom
bugfix/module-boot-once
Open

kevinushey wants to merge 1 commit into
bugfix/module-boot-exceptionsfrom
bugfix/module-boot-once

Conversation

@kevinushey

Copy link
Copy Markdown
Contributor

Fixes #1527. Stacked on #1526 (same macro); the base branch is bugfix/module-boot-exceptions, so the diff here only shows this change. Once #1526 is merged I'll retarget this to master.

Module("name", PACKAGE = ...) calls the module's boot function every time it is given a module name, and the boot function re-ran the RCPP_MODULE body each time. The body adds to a static Rcpp::Module that lives as long as the DLL, so every load appended another copy of each constructor and method overload, which shows up in show() and leaks. See #1527 for the reprex.

Change (inst/include/Rcpp/Module.h, RCPP_MODULE):

  • A static bool flag next to the static Rcpp::Module records that the body has completed; later calls of the boot function skip the body and just return the module pointer. The flag lives in the same DLL instance as the module object, so a DLL that is unloaded and loaded again starts over with a fresh module and flag, as it should.
  • The flag is only set after the body returns normally. If the body throws (now an R error, see turn exceptions during module initialization into r errors #1526), a later load runs it again. That can duplicate whatever was registered before the exception, but that is no worse than today, and the module was unusable anyway.

As with #1526, this is confined to the macro and applies once a package is rebuilt.

Test (inst/tinytest/test_module.R): after sourceCpp() has loaded demoModule, load it twice more with Module(..., mustStart = TRUE) and check that ModuleWorld still has one constructor and one greet() overload. It sits at the end of the file because Module() redefines the module's reference classes.

Verification:

Checklist

  • Code compiles correctly
  • R CMD check still passes all tests (module test files run locally as above)
  • Preferably, new tests were added which fail without the change
  • Document the changes by file in ChangeLog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant