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.

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

Important note<br />

Advanced topics<br />

Extending the OCB<br />

Recall the discussion in the io_write() sample above, about the data area following the<br />

header. To recap, we stated that the bytes following the header may or may not be<br />

complete (i.e., the header may or may not have been read in its entirety from the<br />

client), depending on how much data was read in by the resource manager library.<br />

Then we went on to discuss how it was inefficient to try to “save” a message pass and<br />

to “reuse” the data area. However, things are slightly different <strong>with</strong> devctl(), especially<br />

if the amount of data being transferred is fairly small (as was the case in our<br />

examples). In these cases, there’s a good chance that the data has in fact been read into<br />

the data area, so it is indeed a waste to re-read the data. There is a simple way to tell<br />

how much space you have: the size member of ctp contains the number of bytes that<br />

are available for you starting at the msg parameter. The size of the data area beyond<br />

the end of the message buffer that’s available is calculated by subtracting the size of<br />

the message buffer from the size member of ctp:<br />

data_area_size = ctp -> size - sizeof (*msg);<br />

Note that this size is equally valid when you are returning data to the client (as in the<br />

DCMD_AUDIO_GET_SAMPLE_RATE command).<br />

For anything larger than the allocated region, you’ll want to perform the same<br />

processing we did <strong>with</strong> the io_write() example (above) for getting data from the client,<br />

and you’ll want to allocate a buffer to be used for returning data to the client.<br />

Now that we’ve covered the “basics” of resource managers, it’s time to look at some<br />

more complicated aspects:<br />

• extending the OCB<br />

• extending the attributes structure<br />

• blocking <strong>with</strong>in the resource manager<br />

• returning directory entries<br />

In some cases, you may find the need to extend the OCB. This is relatively painless to<br />

do. The common uses for extending the OCB are to add extra flags you wish to<br />

maintain on a per-open basis. One such flag could be used <strong>with</strong> the io_unblock()<br />

handler to cache the value of the kernel’s _NTO_MI_UNBLOCK_REQ flag. (See the<br />

Message Passing chapter, under “Using the _NTO_MI_UNBLOCK_REQ” for more<br />

details.)<br />

To extend the OCB, you’ll need to provide two functions; one to allocate (and<br />

initialize) the new OCB and one to free it. Then, you’ll need to bind these two<br />

functions into the mount structure. (Yes, this does mean that you’ll need a mount<br />

April 30, 2009 Chapter 5 • Resource Managers 269

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

Saved successfully!

Ooh no, something went wrong!