ports, binaries & iovecs

Vance Shipley vances@REDACTED
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[1].iov_len;
	ctrlp.buf = iov[1].iov_base; 
	datap.len = iov[2].iov_len;
	datap.buf = iov[2].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
a header).

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 mailing list