func finalizeMsg(datap *[]byte) error { hdrp := (*reflect.SliceHeader)(unsafe.Pointer(datap)) if rc, err := C.nn_freemsg(unsafe.Pointer(hdrp.Data)); rc != 0 { return nnError(err) } return nil }
// Recv receives a message from the socket. The flags argument can be zero or // DontWait. func (s *Socket) Recv(flags int) ([]byte, error) { var err error var buf unsafe.Pointer var length C.int if length, err = C.nn_recv(s.socket, unsafe.Pointer(&buf), nn_msg, C.int(flags)); length < 0 { return nil, nnError(err) } // TODO why is the latter variant faster than the zero copy variant? zeroCopy := true if zeroCopy { capacity := int(length) header := &reflect.SliceHeader{ Data: uintptr(buf), Len: capacity, Cap: capacity, } data := *((*[]byte)(unsafe.Pointer(header))) runtime.SetFinalizer(&data, finalizeMsg) return data, nil } else { data := C.GoBytes(buf, length) if rc, err := C.nn_freemsg(buf); rc != 0 { return data, nnError(err) } return data, nil } }