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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Examples<br />

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

}<br />

}<br />

// 8) tell the resource manager library to do the reply, and that it<br />

// was okay<br />

return (EOK);<br />

As you can see, a few of the initial operations performed were identical to those done<br />

in the io_read() example — the iofunc_write_verify() is analogous to the<br />

iofunc_read_verify() function, and the xtype override check is the same.<br />

Step 1<br />

Here we performed much the same processing for the “xtype override” as we did in<br />

the io_read() example, except for the fact that the offset is not stored as part of the<br />

incoming message structure. The reason it’s not stored there is because a common<br />

practice is to use the size of the incoming message structure to determine the starting<br />

point of the actual data being transferred from the client. We take special pains to<br />

ensure the offset of the start of the data (doffset) is correct in the xtype handling code.<br />

Step 2<br />

Here we allocate a buffer that’s big enough for the data. The number of bytes that the<br />

client is writing is presented to us in the nbytes member of the msg union. This is<br />

stuffed automatically by the client’s C library in the write() routine. Note that if we<br />

don’t have sufficient memory to handle the malloc() request, we return the error<br />

number ENOMEM to the client — effectively, we’re passing on the return code to the<br />

client to let it know why its request wasn’t completed.<br />

Step 3<br />

Here we use the helper function resmgr_msgread() to read the entire data content from<br />

the client directly into the newly allocated buffer. In most cases we could have just<br />

used MsgRead(), but in the case where this message is part of a “combine message,”<br />

resmgr_msgread() performs the appropriate “magic” for us (see the “Combine<br />

message” section for more information on why we need to do this.) The parameters to<br />

resmgr_msgread() are fairly straightforward; we give it the internal context pointer<br />

(ctp), the buffer into which we want the data placed (buffer), and the number of bytes<br />

that we wish read (the nbytes member of the message msg union). The last parameter<br />

is the offset into the current message, which we calculated above, in step 1. The offset<br />

effectively skips the header information that the client’s C library implementation of<br />

write() put there, and proceeds directly to the data. This actually brings about two<br />

interesting points:<br />

• We could use an arbitrary offset value to read chunks of the client’s data in any<br />

order and size we want.<br />

• We could use resmgr_msgreadv() (note the “v”) to read data from the client into an<br />

IOV, perhaps describing various buffers, similar to what we did <strong>with</strong> the cache<br />

buffers in the filesystem discussion in the Message Passing chapter.<br />

262 Chapter 5 • Resource Managers April 30, 2009

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

Saved successfully!

Ooh no, something went wrong!