26.02.2014 Views

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

© 2009, <strong>QNX</strong> <strong>Software</strong> <strong>Systems</strong> GmbH & Co. KG. Using message passing<br />

#include <br />

ssize_t write (int fd, const void *buf, size_t nbytes)<br />

{<br />

io_write_t whdr;<br />

iov_t iov [2];<br />

// set up the IOV to point to both parts:<br />

SETIOV (iov + 0, &whdr, sizeof (whdr));<br />

SETIOV (iov + 1, buf, nbytes);<br />

// fill in the io_write_t at the beginning<br />

whdr.type = _IO_WRITE;<br />

whdr.nbytes = nbytes;<br />

// send the message to the server<br />

return (MsgSendv (coid, iov, 2, iov, 1));<br />

}<br />

First of all, notice there’s no malloc() and no memcpy(). Next, notice the use of the<br />

iov_t type. This is a structure that contains an address and length pair, and we’ve<br />

allocated two of them (named iov).<br />

The iov_t type definition is automatically included by , and is<br />

defined as:<br />

typedef struct iovec<br />

{<br />

void *iov_base;<br />

size_t iov_len;<br />

} iov_t;<br />

Given this structure, we fill the address and length pairs <strong>with</strong> the write header (for the<br />

first part) and the data from the client (in the second part). There’s a convenience<br />

macro called SETIOV() that does the assignments for us. It’s formally defined as:<br />

#include <br />

#define SETIOV(_iov, _addr, _len) \<br />

((_iov)->iov_base = (void *)(_addr), \<br />

(_iov)->iov_len = (_len))<br />

SETIOV() accepts an iov_t, and the address and length data to be stuffed into the<br />

IOV.<br />

Also notice that since we’re creating an IOV to point to the header, we can allocate the<br />

header on the stack <strong>with</strong>out using malloc(). This can be a blessing and a curse — it’s a<br />

blessing when the header is quite small, because you avoid the headaches of dynamic<br />

memory allocation, but it can be a curse when the header is huge, because it can<br />

consume a fair chunk of stack space. Generally, the headers are quite small.<br />

In any event, the important work is done by MsgSendv(), which takes almost the same<br />

arguments as the MsgSend() function that we used in the previous example:<br />

#include <br />

int MsgSendv (int coid,<br />

const iov_t *siov,<br />

int sparts,<br />

const iov_t *riov,<br />

int rparts);<br />

April 30, 2009 Chapter 2 • Message Passing 109

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!