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. Using message passing<br />

The kernel transfers the minimum specified by both sizes. In our case, the kernel<br />

would transfer 28 bytes. The server would be unblocked and print out the client’s<br />

message. The remaining 484 bytes (of the 512 byte buffer) will remain unaffected.<br />

We run into the same situation again <strong>with</strong> MsgReply(). The MsgReply() function says<br />

that it wants to transfer 512 bytes, but our client’s MsgSend() function has specified<br />

that a maximum of 200 bytes can be transferred. So the kernel once again transfers the<br />

minimum. In this case, the 200 bytes that the client can accept limits the transfer size.<br />

(One interesting aspect here is that once the server transfers the data, if the client<br />

doesn’t receive all of it, as in our example, there’s no way to get the data back — it’s<br />

gone forever.)<br />

The send-hierarchy<br />

Keep in mind that this “trimming” operation is normal and expected behavior.<br />

When we discuss message passing over a network, you’ll see that there’s a tiny<br />

“gotcha” <strong>with</strong> the amount of data transferred. We’ll see this in “Networked<br />

message-passing differences,” below.<br />

One thing that’s perhaps not obvious in a message-passing environment is the need to<br />

follow a strict send-hierarchy. What this means is that two threads should never send<br />

messages to each other; rather, they should be organized such that each thread<br />

occupies a “level”; all sends go from one level to a higher level, never to the same or<br />

lower level. The problem <strong>with</strong> having two threads send messages to each other is that<br />

eventually you’ll run into the problem of deadlock — both threads are waiting for each<br />

other to reply to their respective messages. Since the threads are blocked, they’ll never<br />

get a chance to run and perform the reply, so you end up <strong>with</strong> two (or more!) hung<br />

threads.<br />

The way to assign the levels to the threads is to put the outermost clients at the highest<br />

level, and work down from there. For example, if you have a graphical user interface<br />

that relies on some database server, and the database server in turn relies on the<br />

filesystem, and the filesystem in turn relies on a block filesystem driver, then you’ve<br />

got a natural hierarchy of different processes. The sends will flow from the outermost<br />

client (the graphical user interface) down to the lower servers; the replies will flow in<br />

the opposite direction.<br />

While this certainly works in the majority of cases, you will encounter situations<br />

where you need to “break” the send hierarchy. This is never done by simply violating<br />

the send hierarchy and sending a message “against the flow,” but rather by using the<br />

MsgDeliverEvent() function, which we’ll take a look at later.<br />

Receive IDs, channels, and other parameters<br />

We haven’t talked about the various parameters in the examples above so that we<br />

could focus just on the message passing. Now let’s take a look.<br />

April 30, 2009 Chapter 2 • Message Passing 97

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

Saved successfully!

Ooh no, something went wrong!