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.

Advanced topics<br />

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

struct sigevent event;<br />

int<br />

rval;<br />

...<br />

// set up the event -- this can be done once<br />

// This or event.sigev_notify = SIGEV_UNBLOCK:<br />

SIGEV_UNBLOCK_INIT (&event);<br />

// set up for 10 second timeout<br />

timeout = 10LL * SEC_NSEC;<br />

TimerTimeout (CLOCK_REALTIME, _NTO_TIMEOUT_JOIN,<br />

&event, &timeout, NULL);<br />

rval = pthread_join (thread_id, NULL);<br />

if (rval == ETIMEDOUT) {<br />

printf ("Thread %d still running after 10 seconds!\n",<br />

thread_id);<br />

}<br />

...<br />

(You’ll find the complete version of tt1.c in the Sample Programs appendix.)<br />

We used the SIGEV_UNBLOCK_INIT() macro to initialize the event structure, but we<br />

could have set the sigev_notify member to SIGEV_UNBLOCK ourselves. Even more<br />

elegantly, we could pass NULL as the struct sigevent — TimerTimeout()<br />

understands this to mean that it should use a SIGEV_UNBLOCK.<br />

If the thread (specified in thread_id) is still running after 10 seconds, then the kernel<br />

call will be timed out — pthread_join() will return <strong>with</strong> an errno of ETIMEDOUT.<br />

You can use another shortcut — by specifying a NULL for the timeout value (ntime in<br />

the formal declaration above), this tells the kernel not to block in the given state. This<br />

can be used for polling. (While polling is generally discouraged, you could use it quite<br />

effectively in the case of the pthread_join() — you’d periodically poll to see if the<br />

thread you’re interested in was finished yet. If not, you could perform other work.)<br />

Here’s a code sample showing a non-blocking pthread_join():<br />

int<br />

pthread_join_nb (int tid, void **rval)<br />

{<br />

TimerTimeout (CLOCK_REALTIME, _NTO_TIMEOUT_JOIN,<br />

NULL, NULL, NULL);<br />

return (pthread_join (tid, rval));<br />

}<br />

Kernel timeouts <strong>with</strong> message passing<br />

Things get a little trickier when you’re using kernel timeouts <strong>with</strong> message passing.<br />

Recall from the Message Passing chapter (in the “Message passing and client/server”<br />

part) that the server may or may not be waiting for a message when the client sends it.<br />

This means that the client could be blocked in either the SEND-blocked state (if the<br />

server hasn’t received the message yet), or the REPLY-blocked state (if the server has<br />

received the message, and hasn’t yet replied). The implication here is that you should<br />

164 Chapter 3 • Clocks, Timers, and <strong>Getting</strong> a Kick Every So Often April 30, 2009

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

Saved successfully!

Ooh no, something went wrong!