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. Pulses<br />

The MsgDeliverEvent() function<br />

(requests for service). Since you’re trying to control the number of “service-providing<br />

threads,” and since some of these threads may need to block, waiting for a pulse to<br />

arrive (for example, from some hardware or from another thread), you’d typically<br />

block the service-providing thread using MsgReceivePulse(). This ensures that a client<br />

request won’t “sneak in” while you’re waiting for the pulse (since MsgReceivePulse()<br />

will receive only a pulse).<br />

As mentioned above in “The send-hierarchy,” there are cases when you need to break<br />

the natural flow of sends.<br />

Such a case might occur if you had a client that sent a message to the server, the result<br />

might not be available for a while, and the client didn’t want to block. Of course, you<br />

could also partly solve this <strong>with</strong> threads, by having the client simply “use up” a thread<br />

on the blocking server call, but this may not scale well for larger systems (where you’d<br />

be using up lots of threads to wait for many different servers). Let’s say you didn’t<br />

want to use a thread, but instead wanted the server to reply immediately to the client,<br />

“I’ll get around to your request shortly.” At this point, since the server replied, the<br />

client is now free to continue processing. Once the server has completed whatever task<br />

the client gave it, the server now needs some way to tell the client, “Hey, wake up, I’m<br />

done.” Obviously, as we saw in the send-hierarchy discussion above, you can’t have<br />

the server send a message to the client, because this might cause deadlock if the client<br />

sent a message to the server at that exact same instant. So, how does the server “send”<br />

a message to a client <strong>with</strong>out violating the send hierarchy?<br />

It’s actually a multi-step operation. Here’s how it works:<br />

1 The client creates a struct sigevent structure, and fills it in.<br />

2 The client sends a message to the server, effectively stating, “Perform this<br />

specific task for me, reply right away, and by the way, here’s a struct<br />

sigevent that you should use to notify me when the work is completed.”<br />

3 The server receives the message (which includes the struct sigevent),<br />

stores the struct sigevent and the receive ID away, and replies immediately<br />

to the client.<br />

4 The client is now running, as is the server.<br />

5 When the server completes the work, the server uses MsgDeliverEvent() to<br />

inform the client that the work is now complete.<br />

We’ll take a look in detail at the struct sigevent in the Clocks, Timers, and<br />

<strong>Getting</strong> a Kick Every So Often chapter, under “How to fill in the struct<br />

sigevent.” For now, just think of the struct sigevent as a “black box” that<br />

somehow contains the event that the server uses to notify the client.<br />

Since the server stored the struct sigevent and the receive ID from the client, the<br />

server can now call MsgDeliverEvent() to deliver the event, as selected by the client, to<br />

the client:<br />

April 30, 2009 Chapter 2 • Message Passing 117

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

Saved successfully!

Ooh no, something went wrong!