[Haskell-cafe] FFI Ptr Question

Michael Jones mike at proclivis.com
Tue Apr 7 04:57:15 UTC 2015

Turns out Set is not called after Get.

So here is what I am thinking:

getValue :: TVar (ForeignPtr CWchar) -> Ptr CInt -> CInt -> CInt -> IO CWString
getValue ptr p r c = do
  s <- if c == 0
    then newCWString "Str 0"
    else newCWString "Str 1"
  sPtr <- newForeignPtr finalizerFree s
  liftIO $ atomically $ writeTVar ptr sPtr
  return s

Create a ForeignPtr and store it in a TVar. After the callback, the CWString will be inside the ForeignPtr until it is no longer referenced. On the second call, TVar will be given a new ForeignPtr, and the previous one will get collected, and finalizerFree will free the CWString.

The next step will be to generate the CWString out of another TVar, rather than the fixed string in the example.

There might be a way to get a Ptr to the original string rather than generating a new string, but I don’t know what goes on in the TVar, so I am suspect of holding a pointer to anything inside it. But with the above, I essentially copy the string and manage its collection.



On Apr 6, 2015, at 11:35 AM, Michael Jones <mike at proclivis.com> wrote:

> Donn,
> My intent was to hold the strings in a TVar, with a thread keeping it up to date, in this case, filtering, adding, etc.
> I need to look at how TVar works. I assume that a read from a TVar produces a value, and if the read from TVar is done in the callback, the pointer has to be freed when the callback exits, or by the C++ code.
> I also recall seeing some code in wxWidgets where after the callback to read is made, it calls another callback to set. It may be intended as a way to free memory. If every read is followed by a set, the set could could free the pointer.
> Either way, the design has dynamic data getting updated by a thread at a rate of change much larger than human interaction (scrolling).
> Mike
> On Apr 6, 2015, at 10:47 AM, Donn Cave <donn at avvanta.com> wrote:
>> Quoth Michael Jones <mike at proclivis.com>,
>>> The problem is newCWString creates a string that must be freed, and
>>> wxWidgets does not free it. This results in a memory leak.
>>> In a real application, I'll probably store a String in a TVar so that
>>> some thread can keep it up to date. I could use other TVars to hold
>>> the CWString and free it each time a new value is created. But, it
>>> would be better if there was some way to guarantee it is freed, even
>>> with exceptions, etc. The best would be if when the function returns,
>>> it automatically freed the string.
>>> Is there a way express the callback function so that it frees the string
>>> after the return?
>> Are you sure that's what you want?  I may be misunderstanding "after
>> the return" - to me, that sounds like right after your getValue callback.
>> That would be approximately the same as freeing it within the callback,
>> right after allocation and initialization.  That's not ideal at all.
>> You'll need to store the string in your application, it seems to me,
>> and pass that value via the callback rather than allocating a new copy
>> each time.
>> 	Donn
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list