[gambit-list] How to properly allocate foreign object?
Marc Feeley
feeley at iro.umontreal.ca
Fri Apr 10 15:49:15 EDT 2020
There are a few issues with your code. First of all, you should use “___return(…);” to return a result (the assignment to ___result_voidstar is deprecated). When Scheme code receives a foreign pointer, there is no “automatic freeing” of the memory done by Gambit. You need to program that explicitly, for example using a will. An alternative would be to create your own type with a release function, but that is probably overkill in this situation. Here’s how I would write the code:
(c-declare "#include <stdlib.h>")
(c-declare "#include <sys/socket.h>")
(c-define-type sockaddr_storage (struct "sockaddr_storage"))
(c-define-type socket-address (pointer sockaddr_storage socket-address))
(define alloc-socket-address
(c-lambda ()
socket-address
"___return(malloc(sizeof(struct sockaddr_storage)));"))
(define free-socket-address
(c-lambda (socket-address)
void
"free(___arg1);"))
(define (make-socket-address)
(let ((sa (alloc-socket-address)))
(if sa
(make-will sa (lambda (sa)
(pp (list 'freeing sa))
(free-socket-address sa))))
sa))
(println "-----------")
(pp (make-socket-address))
(define foo (make-socket-address))
(pp foo)
(println "-----------")
(##gc)
(println "-----------")
(pp (make-socket-address))
(println "-----------")
(##gc)
(println "-----------")
;; prints:
;;
;; -----------
;; #<socket-address #2 0x7fe723405010>
;; #<socket-address #3 0x7fe7234050f0>
;; -----------
;; (freeing #<socket-address #2 0x7fe723405010>)
;; -----------
;; #<socket-address #4 0x7fe723405010>
;; -----------
;; (freeing #<socket-address #4 0x7fe723405010>)
;; -----------
Marc
> On Apr 10, 2020, at 3:12 PM, Jörg F. Wittenberger <Joerg.Wittenberger at softeyes.net> wrote:
>
> Hi,
>
> I'm afraid I don't grock the documentation wrt. memory management of
> foreign bjects.
>
>> I really need a unix domain socket. Actually an abstract socket on
>> Linux.
>
> The example at at hand: a `struct sockaddr_storage`. That is, in
> general, any kind of C struct to allocate.
>
> Likely I'm doing it all wrong. My great excuse(TM): I learned gambit's
> FFI from `gamsock` while adding domain socket support. No, Mam, it's
> not been me. ;-)
>
> # Part I, the easy thing
>
> (c-define-type socket-address
> (pointer (struct "sockaddr_storage") socket-address))
>
> (c-lambda
> (...) socket-address
> "...
> ___result_voidstar = malloc(sizeof(struct sockaddr_storage)));
> ...")
>
> That seems to work. But I'd bet this leaks memory as gamsock never
> frees this memory.
>
> Q: Does it leak? Or is there some gambit magic default?
>
> # Part II, the crazy thing
>
> If I got that right, than what I'd need to fix the leak was to attach a
> /will/ to the socket-address, which would free the storage and return
> ___NO_ERR.
>
> Q: Correct?
>
> If yes, is this a good idea? I'd assume that allocating short lived
> objects from the Scheme heap should be much less expesive. Isn't it?
>
>
> # Part III, how?
>
> 1. How would I allocate a short lived object on the scheme heap?
> 2. Still have it properly tagges as foreign object for type checking.
> (I.e., I know I could allocate a u8vector of the size I need.
> But this is an u8vector for Scheme, which I don't want.)
>
> Thanks
>
> /Jörg
>
>
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://mailman.iro.umontreal.ca/cgi-bin/mailman/listinfo/gambit-list
More information about the Gambit-list
mailing list