I have this struct that has an associated method that simply call a C
function that might take a long time to use. It is defined more or less
like this:

import "C"

type Indexer struct {
  cIndexer *C.Indexer
}

func NewIndexer() *Indexer {
  i := &Indexer{getCIndexerPointer()}
  runtime.SetFinalizer(i, (*Indexer).finalize)
}

func (i *Indexer) finalize() {
  freeCIndexertPointer(i.cIndexer)
}

func (i *Indexer) Commit() {
  callCCommit(i.cIndexer)
}

Then I have some code that uses an indexer object:

func Index() {
  i := NewIndexer()

  // Index documents calling Indexer methods.

  i.Commit()
}

For some corpus, the Commit() call above might take several minutes to
complete. It looks like that if the garbage collector kicks in when it is
running, the runtime thinks that it is ok to collect the object and this
triggers the finalizer that, in turn, deletes the internal C object that,
finally, make the C commit call to crash as the C struct it uses to do its
job was freed.

I am aware that a call to runtime.KeepAlive(i) after the Commit() call
should be enough to sort this up, but I am wondering why it is required at
all in this case. Isn't the fact that a method on a struct type is running
enough to avoid collection? If not, shouldn't it be? Or is this related to
the usage of CGO?

In any case, it was a bit unexpected to me (although I did guess that the
problem was this and adding debug to the finalizer helped confirming it). I
would go as far as to say this looks like a bug.

Thoughts?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to