Commit 1924cba8 authored by Martin Sustrik's avatar Martin Sustrik

memory management in Lisp binding fixed

parent 86d68cbc
...@@ -17,28 +17,51 @@ ...@@ -17,28 +17,51 @@
(in-package :zeromq) (in-package :zeromq)
;; Stolen from CFFI. Uses custom allocator (alloc-fn) instead of foreign-alloc
(defun copy-lisp-string-octets (string alloc-fn &key (encoding cffi::*default-foreign-encoding*)
(null-terminated-p t) (start 0) end)
"Allocate a foreign string containing Lisp string STRING.
The string must be freed with FOREIGN-STRING-FREE."
(check-type string string)
(cffi::with-checked-simple-vector ((string (coerce string 'babel:unicode-string))
(start start) (end end))
(declare (type simple-string string))
(let* ((mapping (cffi::lookup-mapping cffi::*foreign-string-mappings* encoding))
(count (funcall (cffi::octet-counter mapping) string start end 0))
(length (if null-terminated-p
(+ count (cffi::null-terminator-len encoding))
count))
(ptr (funcall alloc-fn length)))
(funcall (cffi::encoder mapping) string start end ptr 0)
(when null-terminated-p
(dotimes (i (cffi::null-terminator-len encoding))
(setf (mem-ref ptr :char (+ count i)) 0)))
(values ptr length))))
(defclass msg () (defclass msg ()
((raw :accessor msg-raw :initform nil) ((raw :accessor msg-raw :initform nil)))
(shared :accessor msg-shared :initform 0 :initarg :shared)))
(defmethod initialize-instance :after ((inst msg) &key size data) (defmethod initialize-instance :after ((inst msg) &key size data)
(let ((obj (foreign-alloc 'msg))) (let ((obj (foreign-alloc 'msg)))
(with-slots (raw shared) inst (tg:finalize inst (lambda ()
(setf raw obj) (%msg-close obj)
(tg:finalize inst (lambda () (foreign-free obj)))
(%msg-close raw) (cond (size (%msg-init-size obj size))
(foreign-free raw))) (data
(when shared (etypecase data
(setf (foreign-slot-value obj 'msg 'shared) (if shared 1 0))) (string (copy-lisp-string-octets
(cond (size (%msg-init-size raw size)) data (lambda (sz)
(data (%msg-init-size obj sz)
(multiple-value-bind (ptr len) (%msg-data obj))))
(etypecase data (array (progn
(string (foreign-string-alloc data)) (%msg-init-size obj (length data))
(array (values (foreign-alloc :uchar :initial-contents data) (let ((ptr (%msg-data obj))
(length data)))) (i -1))
(msg-init-data raw ptr len (callback zmq-free)))) (map nil (lambda (x)
(t (msg-init raw)))))) (setf (mem-aref ptr :uchar (incf i)) x))
data))))))
(t (msg-init obj)))
(setf (msg-raw inst) obj)))
(defclass pollitem () (defclass pollitem ()
((raw :accessor pollitem-raw :initform nil) ((raw :accessor pollitem-raw :initform nil)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment