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 />

Steps 3 & 4<br />

To calculate how many bytes we can actually return to the client, we perform steps 3<br />

and 4, which figure out how many bytes are available on the device (by taking the total<br />

device size from ocb -> attr -> nbytes and subtracting the current offset into<br />

the device). Once we know how many bytes are left, we take the smaller of that<br />

number and the number of bytes that the client specified that they wish to read. For<br />

example, we may have seven bytes left, and the client wants to only read two. In that<br />

case, we can return only two bytes to the client. Alternatively, if the client wanted<br />

4096 bytes, but we had only seven left, we could return only seven bytes.<br />

Step 5<br />

Now that we’ve calculated how many bytes we’re going to return to the client, we<br />

need to do different things based on whether or not we’re returning data. If we are<br />

returning data, then after the check in step 5, we reply to the client <strong>with</strong> the data.<br />

Notice that we use data_string + off to return data starting at the correct offset<br />

(the off is calculated based on the xtype override). Also notice the second parameter to<br />

MsgReply() — it’s documented as the status argument, but in this case we’re using it<br />

to return the number of bytes. This is because the implementation of the client’s read()<br />

function knows that the return value from its MsgSendv() (which is the status<br />

argument to MsgReply(), by the way) is the number of bytes that were read. This is a<br />

common convention.<br />

Step 6<br />

Since we’re returning data from the device, we know that the device has been<br />

accessed. We set the IOFUNC_ATTR_ATIME and IOFUNC_ATTR_DIRTY_TIME bits<br />

in the flags member of the attribute structure. This serves as a reminder to the io_stat()<br />

function that the access time is not valid and should be fetched from the system clock<br />

before replying. If we really wanted to, we could have stuffed the current time into the<br />

atime member of the attributes structure, and cleared the<br />

IOFUNC_ATTR_DIRTY_TIME flag. But this isn’t very efficient, since we’re expecting<br />

to get a lot more read() requests from the client than stat() requests. However, your<br />

usage patterns may dictate otherwise.<br />

So which time does the client see when it finally does call stat()? The<br />

iofunc_stat_default() function provided by the resource manager library will look at<br />

the flags member of the attribute structure to see if the times are valid (the atime,<br />

ctime, and mtime fields). If they are not (as will be the case after our io_read() has<br />

been called that returned data), the iofunc_stat_default() function will update the<br />

time(s) <strong>with</strong> the current time. The real value of the time is also updated on a close(), as<br />

you’d expect.<br />

258 Chapter 5 • Resource Managers April 30, 2009

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

Saved successfully!

Ooh no, something went wrong!