Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it safe to pass a GC'ed pointer to C? #3290

Open
joelberkeley opened this issue May 26, 2024 · 0 comments
Open

Is it safe to pass a GC'ed pointer to C? #3290

joelberkeley opened this issue May 26, 2024 · 0 comments

Comments

@joelberkeley
Copy link
Contributor

joelberkeley commented May 26, 2024

In the following freehand code I'm concerned that Idris can garbage collect the Foo pointer while it's still in use. I have had mixed experience with using this pattern. Sometimes I get memory errors, sometimes not. But when I did debug it it seemed to fall over after the first time the Idris GC ran.

struct Foo { int n; };

Foo* mkfoo () {
  return new Foo{0};
}

int slow (Foo* foo) {
  usleep(9999999999);  // Idris runs GC here
  return foo->n;       // foo no longer allocated
}
data Foo = MkFoo GCAnyPtr

%foreign "mkfoo"
mkfoo : PrimIO AnyPtr

foo : IO Foo
foo = do
  foo <- primIO mkfoo
  foo <- onCollectAny foo free
  pure (MkFoo foo)

%foreign "slow"
prim__slow : GCAnyPtr -> Int

slow : Foo -> Int
slow (MkFoo foo) = prim__slow foo

main : IO ()
main = do
  foo <- mkfoo
  printLn (slow foo)  

If this is a bug, perhaps it's OK if it remains as a limitation of finalisers onCollect[Any], if it's documented VERY LOUDLY cos it defeats the whole purpose of the function when used as above, i.e. safe automatic memory management. That said, I can't see when you'd use it in any other way. Would you ever have a pointer that you don't pass back to C? In what scenario are finalisers safe?

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

No branches or pull requests

1 participant