ports, binaries & iovecs
Fri Oct 11 07:34:42 CEST 2002
Thanks for the quick and detailed response! I'm now having to think
through what I am doing and how it will be used. It is of course
nice to avoid copying if unecessary but I shouldn't spend too much
time just now worrying about it (first make it work ...).
My driver uses STREAMS so when it gets the data it will send it using
putmsg(). I had naively thought that I would construct the control
and data buffers using bit syntax in Erlang and send it to the driver:
port_command(Port, [<<Control>>, <<Data>>])
In my outputv() driver callback I expected to receive two iovecs
which I could pass directrly to putmsg():
struct strbuf ctrlp, datap;
ctrlp.len = iov.iov_len;
ctrlp.buf = iov.iov_base;
datap.len = iov.iov_len;
datap.buf = iov.iov_base;
putmsg(fd, &ctrlp, &datap, 0);
... and Bob's your uncle! Nope.
The first thing I found is that since I never send both a control
and a data portion at once both of the following get flattened
down to one iovec and there is no way to differentiate between them.
port_command(Port, [<<Control>>, <<>>])
port_command(Port, [<<>>, <<Data>>])
I then found out just how complex it really is. Thanks again.
I'll either have to accept copying everything or optimize the most
common, or expensive, case.
The next thing I started to realize is that the driver queue also
gets flattened. If I enqueue the whole received ErlIOVec it skips
the empty first iovec. Actually somewhat handy as I don't use it
(the emulator sticks it in there so that the inet drivers can build
My driver is not serialized but rather message based so the iovecs
are only handy if they remain contiguous and sensible. Hmmm ...
More information about the erlang-questions