<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=9"/> <meta name="generator" content="Doxygen 1.8.5"/> <title>Polling and timing</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="dynsections.js"></script> <link href="doxygen.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="top"><!-- do not remove this div, it is closed by doxygen! --> <div id="titlearea"> <table cellspacing="0" cellpadding="0"> <tbody> <tr style="height: 56px;"> <td style="padding-left: 0.5em;"> <div id="projectbrief">eXpand your USB potential</div> </td> </tr> </tbody> </table> </div> <!-- end header part --> <!-- Generated by Doxygen 1.8.5 --> <div id="navrow1" class="tabs"> <ul class="tablist"> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> </ul> </div> </div><!-- top --> <div class="header"> <div class="summary"> <a href="#nested-classes">Data Structures</a> | <a href="#typedef-members">Typedefs</a> | <a href="#func-members">Functions</a> </div> <div class="headertitle"> <div class="title">Polling and timing</div> </div> </div><!--header--> <div class="contents"> <p>This page documents libusbx's functions for polling events and timing. <a href="#details">More...</a></p> <table class="memberdecls"> <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> Data Structures</h2></td></tr> <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a></td></tr> <tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">File descriptor for polling. <a href="structlibusb__pollfd.html#details">More...</a><br/></td></tr> <tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> </table><table class="memberdecls"> <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a> Typedefs</h2></td></tr> <tr class="memitem:gace4a3cb954fbc69c43b734fe2202f027"><td class="memItemLeft" align="right" valign="top">typedef void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#gace4a3cb954fbc69c43b734fe2202f027">libusb_pollfd_added_cb</a> )(int fd, short events, void *user_data)</td></tr> <tr class="memdesc:gace4a3cb954fbc69c43b734fe2202f027"><td class="mdescLeft"> </td><td class="mdescRight">Callback function, invoked when a new file descriptor should be added to the set of file descriptors monitored for events. <a href="#gace4a3cb954fbc69c43b734fe2202f027">More...</a><br/></td></tr> <tr class="separator:gace4a3cb954fbc69c43b734fe2202f027"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga91a1f6a5fe01484cb308913a5e2b38e1"><td class="memItemLeft" align="right" valign="top">typedef void(* </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga91a1f6a5fe01484cb308913a5e2b38e1">libusb_pollfd_removed_cb</a> )(int fd, void *user_data)</td></tr> <tr class="memdesc:ga91a1f6a5fe01484cb308913a5e2b38e1"><td class="mdescLeft"> </td><td class="mdescRight">Callback function, invoked when a file descriptor should be removed from the set of file descriptors being monitored for events. <a href="#ga91a1f6a5fe01484cb308913a5e2b38e1">More...</a><br/></td></tr> <tr class="separator:ga91a1f6a5fe01484cb308913a5e2b38e1"><td class="memSeparator" colspan="2"> </td></tr> </table><table class="memberdecls"> <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a> Functions</h2></td></tr> <tr class="memitem:ga6e5a116d5c9498ca4a0e29587fec1a05"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga6e5a116d5c9498ca4a0e29587fec1a05">libusb_try_lock_events</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:ga6e5a116d5c9498ca4a0e29587fec1a05"><td class="mdescLeft"> </td><td class="mdescRight">Attempt to acquire the event handling lock. <a href="#ga6e5a116d5c9498ca4a0e29587fec1a05">More...</a><br/></td></tr> <tr class="separator:ga6e5a116d5c9498ca4a0e29587fec1a05"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:gaa72153938dc4f34decfacbc6cc6237ef"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#gaa72153938dc4f34decfacbc6cc6237ef">libusb_lock_events</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:gaa72153938dc4f34decfacbc6cc6237ef"><td class="mdescLeft"> </td><td class="mdescRight">Acquire the event handling lock, blocking until successful acquisition if it is contended. <a href="#gaa72153938dc4f34decfacbc6cc6237ef">More...</a><br/></td></tr> <tr class="separator:gaa72153938dc4f34decfacbc6cc6237ef"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:gacefbeabdd3409490dc4678f00779c165"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#gacefbeabdd3409490dc4678f00779c165">libusb_unlock_events</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:gacefbeabdd3409490dc4678f00779c165"><td class="mdescLeft"> </td><td class="mdescRight">Release the lock previously acquired with <a class="el" href="group__poll.html#ga6e5a116d5c9498ca4a0e29587fec1a05" title="Attempt to acquire the event handling lock. ">libusb_try_lock_events()</a> or <a class="el" href="group__poll.html#gaa72153938dc4f34decfacbc6cc6237ef" title="Acquire the event handling lock, blocking until successful acquisition if it is contended. ">libusb_lock_events()</a>. <a href="#gacefbeabdd3409490dc4678f00779c165">More...</a><br/></td></tr> <tr class="separator:gacefbeabdd3409490dc4678f00779c165"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga63592b28c265185d9469d1e6920d8373"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga63592b28c265185d9469d1e6920d8373">libusb_event_handling_ok</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:ga63592b28c265185d9469d1e6920d8373"><td class="mdescLeft"> </td><td class="mdescRight">Determine if it is still OK for this thread to be doing event handling. <a href="#ga63592b28c265185d9469d1e6920d8373">More...</a><br/></td></tr> <tr class="separator:ga63592b28c265185d9469d1e6920d8373"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga3a0a6e8be310c20f1ca68722149f9dbf"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga3a0a6e8be310c20f1ca68722149f9dbf">libusb_event_handler_active</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:ga3a0a6e8be310c20f1ca68722149f9dbf"><td class="mdescLeft"> </td><td class="mdescRight">Determine if an active thread is handling events (i.e. <a href="#ga3a0a6e8be310c20f1ca68722149f9dbf">More...</a><br/></td></tr> <tr class="separator:ga3a0a6e8be310c20f1ca68722149f9dbf"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga150865a3f35c38173d688efa7ee52929"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga150865a3f35c38173d688efa7ee52929">libusb_lock_event_waiters</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:ga150865a3f35c38173d688efa7ee52929"><td class="mdescLeft"> </td><td class="mdescRight">Acquire the event waiters lock. <a href="#ga150865a3f35c38173d688efa7ee52929">More...</a><br/></td></tr> <tr class="separator:ga150865a3f35c38173d688efa7ee52929"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga41d7716458c11ee02d0deb19a31233ed"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga41d7716458c11ee02d0deb19a31233ed">libusb_unlock_event_waiters</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:ga41d7716458c11ee02d0deb19a31233ed"><td class="mdescLeft"> </td><td class="mdescRight">Release the event waiters lock. <a href="#ga41d7716458c11ee02d0deb19a31233ed">More...</a><br/></td></tr> <tr class="separator:ga41d7716458c11ee02d0deb19a31233ed"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:gae22755d523560be2867be7d09034ca50"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#gae22755d523560be2867be7d09034ca50">libusb_wait_for_event</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, struct timeval *tv)</td></tr> <tr class="memdesc:gae22755d523560be2867be7d09034ca50"><td class="mdescLeft"> </td><td class="mdescRight">Wait for another thread to signal completion of an event. <a href="#gae22755d523560be2867be7d09034ca50">More...</a><br/></td></tr> <tr class="separator:gae22755d523560be2867be7d09034ca50"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga43e52b912a760b41a0cf8a4a472fbd5b"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b">libusb_handle_events_timeout_completed</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, struct timeval *tv, int *completed)</td></tr> <tr class="memdesc:ga43e52b912a760b41a0cf8a4a472fbd5b"><td class="mdescLeft"> </td><td class="mdescRight">Handle any pending events. <a href="#ga43e52b912a760b41a0cf8a4a472fbd5b">More...</a><br/></td></tr> <tr class="separator:ga43e52b912a760b41a0cf8a4a472fbd5b"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga6deff4c7d3a6c04bb9ec9fd259b48933"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933">libusb_handle_events_timeout</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, struct timeval *tv)</td></tr> <tr class="memdesc:ga6deff4c7d3a6c04bb9ec9fd259b48933"><td class="mdescLeft"> </td><td class="mdescRight">Handle any pending events. <a href="#ga6deff4c7d3a6c04bb9ec9fd259b48933">More...</a><br/></td></tr> <tr class="separator:ga6deff4c7d3a6c04bb9ec9fd259b48933"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga4989086e3f0327f3886a4c474ec7c327"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327">libusb_handle_events</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:ga4989086e3f0327f3886a4c474ec7c327"><td class="mdescLeft"> </td><td class="mdescRight">Handle any pending events in blocking mode. <a href="#ga4989086e3f0327f3886a4c474ec7c327">More...</a><br/></td></tr> <tr class="separator:ga4989086e3f0327f3886a4c474ec7c327"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga0bc99f39e4cf5ad393cd5936c36037d1"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga0bc99f39e4cf5ad393cd5936c36037d1">libusb_handle_events_completed</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, int *completed)</td></tr> <tr class="memdesc:ga0bc99f39e4cf5ad393cd5936c36037d1"><td class="mdescLeft"> </td><td class="mdescRight">Handle any pending events in blocking mode. <a href="#ga0bc99f39e4cf5ad393cd5936c36037d1">More...</a><br/></td></tr> <tr class="separator:ga0bc99f39e4cf5ad393cd5936c36037d1"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga71da081f97afa3bf68aed8e372254e8f"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga71da081f97afa3bf68aed8e372254e8f">libusb_handle_events_locked</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, struct timeval *tv)</td></tr> <tr class="memdesc:ga71da081f97afa3bf68aed8e372254e8f"><td class="mdescLeft"> </td><td class="mdescRight">Handle any pending events by polling file descriptors, without checking if any other threads are already doing so. <a href="#ga71da081f97afa3bf68aed8e372254e8f">More...</a><br/></td></tr> <tr class="separator:ga71da081f97afa3bf68aed8e372254e8f"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:gae7a654315636bebf404c1784429f06df"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#gae7a654315636bebf404c1784429f06df">libusb_pollfds_handle_timeouts</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:gae7a654315636bebf404c1784429f06df"><td class="mdescLeft"> </td><td class="mdescRight">Determines whether your application must apply special timing considerations when monitoring libusbx's file descriptors. <a href="#gae7a654315636bebf404c1784429f06df">More...</a><br/></td></tr> <tr class="separator:gae7a654315636bebf404c1784429f06df"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga5bc6f5bc71a43845244912da6679f634"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634">libusb_get_next_timeout</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, struct timeval *tv)</td></tr> <tr class="memdesc:ga5bc6f5bc71a43845244912da6679f634"><td class="mdescLeft"> </td><td class="mdescRight">Determine the next internal timeout that libusbx needs to handle. <a href="#ga5bc6f5bc71a43845244912da6679f634">More...</a><br/></td></tr> <tr class="separator:ga5bc6f5bc71a43845244912da6679f634"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:ga1b7b2deb193f2e9ffda5e727361d7e67"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#ga1b7b2deb193f2e9ffda5e727361d7e67">libusb_set_pollfd_notifiers</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx, <a class="el" href="group__poll.html#gace4a3cb954fbc69c43b734fe2202f027">libusb_pollfd_added_cb</a> added_cb, <a class="el" href="group__poll.html#ga91a1f6a5fe01484cb308913a5e2b38e1">libusb_pollfd_removed_cb</a> removed_cb, void *user_data)</td></tr> <tr class="memdesc:ga1b7b2deb193f2e9ffda5e727361d7e67"><td class="mdescLeft"> </td><td class="mdescRight">Register notification functions for file descriptor additions/removals. <a href="#ga1b7b2deb193f2e9ffda5e727361d7e67">More...</a><br/></td></tr> <tr class="separator:ga1b7b2deb193f2e9ffda5e727361d7e67"><td class="memSeparator" colspan="2"> </td></tr> <tr class="memitem:gab1a72869a926552b27a6c667695df3a2"><td class="memItemLeft" align="right" valign="top">struct <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> ** </td><td class="memItemRight" valign="bottom"><a class="el" href="group__poll.html#gab1a72869a926552b27a6c667695df3a2">libusb_get_pollfds</a> (<a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> *ctx)</td></tr> <tr class="memdesc:gab1a72869a926552b27a6c667695df3a2"><td class="mdescLeft"> </td><td class="mdescRight">Retrieve a list of file descriptors that should be polled by your main loop as libusbx event sources. <a href="#gab1a72869a926552b27a6c667695df3a2">More...</a><br/></td></tr> <tr class="separator:gab1a72869a926552b27a6c667695df3a2"><td class="memSeparator" colspan="2"> </td></tr> </table> <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> <p>This page documents libusbx's functions for polling events and timing. </p> <p>These functions are only necessary for users of the <a class="el" href="group__asyncio.html">asynchronous API</a>. If you are only using the simpler <a class="el" href="group__syncio.html">synchronous API</a> then you do not need to ever call these functions.</p> <p>The justification for the functionality described here has already been discussed in the <a class="el" href="group__asyncio.html#asyncevent">event handling</a> section of the asynchronous API documentation. In summary, libusbx does not create internal threads for event processing and hence relies on your application calling into libusbx at certain points in time so that pending events can be handled.</p> <p>Your main loop is probably already calling poll() or select() or a variant on a set of file descriptors for other event sources (e.g. keyboard button presses, mouse movements, network sockets, etc). You then add libusbx's file descriptors to your poll()/select() calls, and when activity is detected on such descriptors you know it is time to call <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a>.</p> <p>There is one final event handling complication. libusbx supports asynchronous transfers which time out after a specified time period.</p> <p>On some platforms a timerfd is used, so the timeout handling is just another fd, on other platforms this requires that libusbx is called into at or after the timeout to handle it. So, in addition to considering libusbx's file descriptors in your main event loop, you must also consider that libusbx sometimes needs to be called into at fixed points in time even when there is no file descriptor activity, see <a class="el" href="group__poll.html#polltime">Notes on time-based events</a> details.</p> <p>In order to know precisely when libusbx needs to be called into, libusbx offers you a set of pollable file descriptors and information about when the next timeout expires.</p> <p>If you are using the asynchronous I/O API, you must take one of the two following options, otherwise your I/O will not complete.</p> <h1><a class="anchor" id="pollsimple"></a> The simple option</h1> <p>If your application revolves solely around libusbx and does not need to handle other event sources, you can have a program structure as follows: </p> <div class="fragment"><div class="line"><span class="comment">// initialize libusbx</span></div> <div class="line"><span class="comment">// find and open device</span></div> <div class="line"><span class="comment">// maybe fire off some initial async I/O</span></div> <div class="line"></div> <div class="line"><span class="keywordflow">while</span> (user_has_not_requested_exit)</div> <div class="line"> <a class="code" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327">libusb_handle_events</a>(ctx);</div> <div class="line"></div> <div class="line"><span class="comment">// clean up and exit</span></div> </div><!-- fragment --><p>With such a simple main loop, you do not have to worry about managing sets of file descriptors or handling timeouts. <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a> will handle those details internally.</p> <h1><a class="anchor" id="pollmain"></a> The more advanced option</h1> <dl class="section note"><dt>Note</dt><dd>This functionality is currently only available on Unix-like platforms. On Windows, <a class="el" href="group__poll.html#gab1a72869a926552b27a6c667695df3a2" title="Retrieve a list of file descriptors that should be polled by your main loop as libusbx event sources...">libusb_get_pollfds()</a> simply returns NULL. Applications which want to support Windows are advised to use an <a class="el" href="group__asyncio.html#eventthread">event handling thread</a> instead.</dd></dl> <p>In more advanced applications, you will already have a main loop which is monitoring other event sources: network sockets, X11 events, mouse movements, etc. Through exposing a set of file descriptors, libusbx is designed to cleanly integrate into such main loops.</p> <p>In addition to polling file descriptors for the other event sources, you take a set of file descriptors from libusbx and monitor those too. When you detect activity on libusbx's file descriptors, you call <a class="el" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933" title="Handle any pending events. ">libusb_handle_events_timeout()</a> in non-blocking mode.</p> <p>What's more, libusbx may also need to handle events at specific moments in time. No file descriptor activity is generated at these times, so your own application needs to be continually aware of when the next one of these moments occurs (through calling <a class="el" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634" title="Determine the next internal timeout that libusbx needs to handle. ">libusb_get_next_timeout()</a>), and then it needs to call <a class="el" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933" title="Handle any pending events. ">libusb_handle_events_timeout()</a> in non-blocking mode when these moments occur. This means that you need to adjust your poll()/select() timeout accordingly.</p> <p>libusbx provides you with a set of file descriptors to poll and expects you to poll all of them, treating them as a single entity. The meaning of each file descriptor in the set is an internal implementation detail, platform-dependent and may vary from release to release. Don't try and interpret the meaning of the file descriptors, just do as libusbx indicates, polling all of them at once.</p> <p>In pseudo-code, you want something that looks like: </p> <div class="fragment"><div class="line"><span class="comment">// initialise libusbx</span></div> <div class="line"></div> <div class="line"><a class="code" href="group__poll.html#gab1a72869a926552b27a6c667695df3a2">libusb_get_pollfds</a>(ctx)</div> <div class="line">while (user has not requested application exit) {</div> <div class="line"> <a class="code" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634">libusb_get_next_timeout</a>(ctx);</div> <div class="line"> poll(on libusbx file descriptors plus any other event sources of interest,</div> <div class="line"> <span class="keyword">using</span> a <a class="code" href="structlibusb__transfer.html#a9a12af15ca5b482f5dcaebd26a848cbb">timeout</a> no larger than the value libusbx just suggested)</div> <div class="line"> <span class="keywordflow">if</span> (poll() indicated activity on libusbx file descriptors)</div> <div class="line"> <a class="code" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933">libusb_handle_events_timeout</a>(ctx, &zero_tv);</div> <div class="line"> <span class="keywordflow">if</span> (time has elapsed to or beyond the libusbx <a class="code" href="structlibusb__transfer.html#a9a12af15ca5b482f5dcaebd26a848cbb">timeout</a>)</div> <div class="line"> <a class="code" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933">libusb_handle_events_timeout</a>(ctx, &zero_tv);</div> <div class="line"> <span class="comment">// handle events from other sources here</span></div> <div class="line">}</div> <div class="line"></div> <div class="line"><span class="comment">// clean up and exit</span></div> </div><!-- fragment --><h2><a class="anchor" id="polltime"></a> Notes on time-based events</h2> <p>The above complication with having to track time and call into libusbx at specific moments is a bit of a headache. For maximum compatibility, you do need to write your main loop as above, but you may decide that you can restrict the supported platforms of your application and get away with a more simplistic scheme.</p> <p>These time-based event complications are <b>not</b> required on the following platforms:</p> <ul> <li>Darwin</li> <li>Linux, provided that the following version requirements are satisfied:<ul> <li>Linux v2.6.27 or newer, compiled with timerfd support</li> <li>glibc v2.9 or newer</li> <li>libusbx v1.0.5 or newer</li> </ul> </li> </ul> <p>Under these configurations, <a class="el" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634" title="Determine the next internal timeout that libusbx needs to handle. ">libusb_get_next_timeout()</a> will <em>always</em> return 0, so your main loop can be simplified to: </p> <div class="fragment"><div class="line"><span class="comment">// initialise libusbx</span></div> <div class="line"></div> <div class="line"><a class="code" href="group__poll.html#gab1a72869a926552b27a6c667695df3a2">libusb_get_pollfds</a>(ctx)</div> <div class="line">while (user has not requested application exit) {</div> <div class="line"> poll(on libusbx file descriptors plus any other event sources of interest,</div> <div class="line"> <span class="keyword">using</span> any <a class="code" href="structlibusb__transfer.html#a9a12af15ca5b482f5dcaebd26a848cbb">timeout</a> that you like)</div> <div class="line"> <span class="keywordflow">if</span> (poll() indicated activity on libusbx file descriptors)</div> <div class="line"> <a class="code" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933">libusb_handle_events_timeout</a>(ctx, &zero_tv);</div> <div class="line"> <span class="comment">// handle events from other sources here</span></div> <div class="line">}</div> <div class="line"></div> <div class="line"><span class="comment">// clean up and exit</span></div> </div><!-- fragment --><p>Do remember that if you simplify your main loop to the above, you will lose compatibility with some platforms (including legacy Linux platforms, and <em>any future platforms supported by libusbx which may have time-based event requirements</em>). The resultant problems will likely appear as strange bugs in your application.</p> <p>You can use the <a class="el" href="group__poll.html#gae7a654315636bebf404c1784429f06df" title="Determines whether your application must apply special timing considerations when monitoring libusbx'...">libusb_pollfds_handle_timeouts()</a> function to do a runtime check to see if it is safe to ignore the time-based event complications. If your application has taken the shortcut of ignoring libusbx's next timeout in your main loop, then you are advised to check the return value of <a class="el" href="group__poll.html#gae7a654315636bebf404c1784429f06df" title="Determines whether your application must apply special timing considerations when monitoring libusbx'...">libusb_pollfds_handle_timeouts()</a> during application startup, and to abort if the platform does suffer from these timing complications.</p> <h2><a class="anchor" id="fdsetchange"></a> Changes in the file descriptor set</h2> <p>The set of file descriptors that libusbx uses as event sources may change during the life of your application. Rather than having to repeatedly call <a class="el" href="group__poll.html#gab1a72869a926552b27a6c667695df3a2" title="Retrieve a list of file descriptors that should be polled by your main loop as libusbx event sources...">libusb_get_pollfds()</a>, you can set up notification functions for when the file descriptor set changes using <a class="el" href="group__poll.html#ga1b7b2deb193f2e9ffda5e727361d7e67" title="Register notification functions for file descriptor additions/removals. ">libusb_set_pollfd_notifiers()</a>.</p> <h2><a class="anchor" id="mtissues"></a> Multi-threaded considerations</h2> <p>Unfortunately, the situation is complicated further when multiple threads come into play. If two threads are monitoring the same file descriptors, the fact that only one thread will be woken up when an event occurs causes some headaches.</p> <p>The events lock, event waiters lock, and <a class="el" href="group__poll.html#ga71da081f97afa3bf68aed8e372254e8f" title="Handle any pending events by polling file descriptors, without checking if any other threads are alre...">libusb_handle_events_locked()</a> entities are added to solve these problems. You do not need to be concerned with these entities otherwise.</p> <p>See the extra documentation: <a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </p> <h2 class="groupheader">Typedef Documentation</h2> <a class="anchor" id="gace4a3cb954fbc69c43b734fe2202f027"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">typedef void( * libusb_pollfd_added_cb)(int fd, short events, void *user_data)</td> </tr> </table> </div><div class="memdoc"> <p>Callback function, invoked when a new file descriptor should be added to the set of file descriptors monitored for events. </p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">fd</td><td>the new file descriptor </td></tr> <tr><td class="paramname">events</td><td>events to monitor for, see <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> for a description </td></tr> <tr><td class="paramname">user_data</td><td>User data pointer specified in <a class="el" href="group__poll.html#ga1b7b2deb193f2e9ffda5e727361d7e67" title="Register notification functions for file descriptor additions/removals. ">libusb_set_pollfd_notifiers()</a> call </td></tr> </table> </dd> </dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="group__poll.html#ga1b7b2deb193f2e9ffda5e727361d7e67" title="Register notification functions for file descriptor additions/removals. ">libusb_set_pollfd_notifiers()</a> </dd></dl> </div> </div> <a class="anchor" id="ga91a1f6a5fe01484cb308913a5e2b38e1"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">typedef void( * libusb_pollfd_removed_cb)(int fd, void *user_data)</td> </tr> </table> </div><div class="memdoc"> <p>Callback function, invoked when a file descriptor should be removed from the set of file descriptors being monitored for events. </p> <p>After returning from this callback, do not use that file descriptor again. </p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">fd</td><td>the file descriptor to stop monitoring </td></tr> <tr><td class="paramname">user_data</td><td>User data pointer specified in <a class="el" href="group__poll.html#ga1b7b2deb193f2e9ffda5e727361d7e67" title="Register notification functions for file descriptor additions/removals. ">libusb_set_pollfd_notifiers()</a> call </td></tr> </table> </dd> </dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="group__poll.html#ga1b7b2deb193f2e9ffda5e727361d7e67" title="Register notification functions for file descriptor additions/removals. ">libusb_set_pollfd_notifiers()</a> </dd></dl> </div> </div> <h2 class="groupheader">Function Documentation</h2> <a class="anchor" id="ga6e5a116d5c9498ca4a0e29587fec1a05"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_try_lock_events </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Attempt to acquire the event handling lock. </p> <p>This lock is used to ensure that only one thread is monitoring libusbx event sources at any one time.</p> <p>You only need to use this lock if you are developing an application which calls poll() or select() on libusbx's file descriptors directly. If you stick to libusbx's event handling loop functions (e.g. <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a>) then you do not need to be concerned with this locking.</p> <p>While holding this lock, you are trusted to actually be handling events. If you are no longer handling events, you must call <a class="el" href="group__poll.html#gacefbeabdd3409490dc4678f00779c165" title="Release the lock previously acquired with libusb_try_lock_events() or libusb_lock_events(). ">libusb_unlock_events()</a> as soon as possible.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 if the lock was obtained successfully </dd> <dd> 1 if the lock was not obtained (i.e. another thread holds the lock) </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="gaa72153938dc4f34decfacbc6cc6237ef"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">void libusb_lock_events </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Acquire the event handling lock, blocking until successful acquisition if it is contended. </p> <p>This lock is used to ensure that only one thread is monitoring libusbx event sources at any one time.</p> <p>You only need to use this lock if you are developing an application which calls poll() or select() on libusbx's file descriptors directly. If you stick to libusbx's event handling loop functions (e.g. <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a>) then you do not need to be concerned with this locking.</p> <p>While holding this lock, you are trusted to actually be handling events. If you are no longer handling events, you must call <a class="el" href="group__poll.html#gacefbeabdd3409490dc4678f00779c165" title="Release the lock previously acquired with libusb_try_lock_events() or libusb_lock_events(). ">libusb_unlock_events()</a> as soon as possible.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="gacefbeabdd3409490dc4678f00779c165"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">void libusb_unlock_events </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Release the lock previously acquired with <a class="el" href="group__poll.html#ga6e5a116d5c9498ca4a0e29587fec1a05" title="Attempt to acquire the event handling lock. ">libusb_try_lock_events()</a> or <a class="el" href="group__poll.html#gaa72153938dc4f34decfacbc6cc6237ef" title="Acquire the event handling lock, blocking until successful acquisition if it is contended. ">libusb_lock_events()</a>. </p> <p>Releasing this lock will wake up any threads blocked on <a class="el" href="group__poll.html#gae22755d523560be2867be7d09034ca50" title="Wait for another thread to signal completion of an event. ">libusb_wait_for_event()</a>.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="ga63592b28c265185d9469d1e6920d8373"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_event_handling_ok </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Determine if it is still OK for this thread to be doing event handling. </p> <p>Sometimes, libusbx needs to temporarily pause all event handlers, and this is the function you should use before polling file descriptors to see if this is the case.</p> <p>If this function instructs your thread to give up the events lock, you should just continue the usual logic that is documented in <a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a>. On the next iteration, your thread will fail to obtain the events lock, and will hence become an event waiter.</p> <p>This function should be called while the events lock is held: you don't need to worry about the results of this function if your thread is not the current event handler.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>1 if event handling can start or continue </dd> <dd> 0 if this thread must give up the events lock </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html#fullstory">Multi-threaded I/O: the full story</a> </dd></dl> </div> </div> <a class="anchor" id="ga3a0a6e8be310c20f1ca68722149f9dbf"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_event_handler_active </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Determine if an active thread is handling events (i.e. </p> <p>if anyone is holding the event handling lock).</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>1 if a thread is handling events </dd> <dd> 0 if there are no threads currently handling events </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="ga150865a3f35c38173d688efa7ee52929"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">void libusb_lock_event_waiters </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Acquire the event waiters lock. </p> <p>This lock is designed to be obtained under the situation where you want to be aware when events are completed, but some other thread is event handling so calling <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a> is not allowed.</p> <p>You then obtain this lock, re-check that another thread is still handling events, then call <a class="el" href="group__poll.html#gae22755d523560be2867be7d09034ca50" title="Wait for another thread to signal completion of an event. ">libusb_wait_for_event()</a>.</p> <p>You only need to use this lock if you are developing an application which calls poll() or select() on libusbx's file descriptors directly, <b>and</b> may potentially be handling events from 2 threads simultaenously. If you stick to libusbx's event handling loop functions (e.g. <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a>) then you do not need to be concerned with this locking.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="ga41d7716458c11ee02d0deb19a31233ed"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">void libusb_unlock_event_waiters </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Release the event waiters lock. </p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="gae22755d523560be2867be7d09034ca50"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_wait_for_event </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct timeval * </td> <td class="paramname"><em>tv</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Wait for another thread to signal completion of an event. </p> <p>Must be called with the event waiters lock held, see <a class="el" href="group__poll.html#ga150865a3f35c38173d688efa7ee52929" title="Acquire the event waiters lock. ">libusb_lock_event_waiters()</a>.</p> <p>This function will block until any of the following conditions are met:</p> <ol type="1"> <li>The timeout expires</li> <li>A transfer completes</li> <li>A thread releases the event handling lock through <a class="el" href="group__poll.html#gacefbeabdd3409490dc4678f00779c165" title="Release the lock previously acquired with libusb_try_lock_events() or libusb_lock_events(). ">libusb_unlock_events()</a></li> </ol> <p>Condition 1 is obvious. Condition 2 unblocks your thread <em>after</em> the callback for the transfer has completed. Condition 3 is important because it means that the thread that was previously handling events is no longer doing so, so if any events are to complete, another thread needs to step up and start event handling.</p> <p>This function releases the event waiters lock before putting your thread to sleep, and reacquires the lock as it is being woken up.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">tv</td><td>maximum timeout for this blocking function. A NULL value indicates unlimited timeout. </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 after a transfer completes or another thread stops event handling </dd> <dd> 1 if the timeout expired </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="ga43e52b912a760b41a0cf8a4a472fbd5b"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_handle_events_timeout_completed </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct timeval * </td> <td class="paramname"><em>tv</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">int * </td> <td class="paramname"><em>completed</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Handle any pending events. </p> <p>libusbx determines "pending events" by checking if any timeouts have expired and by checking the set of file descriptors for activity.</p> <p>If a zero timeval is passed, this function will handle any already-pending events and then immediately return in non-blocking style.</p> <p>If a non-zero timeval is passed and no events are currently pending, this function will block waiting for events to handle up until the specified timeout. If an event arrives or a signal is raised, this function will return early.</p> <p>If the parameter completed is not NULL then <em>after obtaining the event handling lock</em> this function will return immediately if the integer pointed to is not 0. This allows for race free waiting for the completion of a specific transfer.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">tv</td><td>the maximum time to block waiting for events, or an all zero timeval struct for non-blocking mode </td></tr> <tr><td class="paramname">completed</td><td>pointer to completion integer to check, or NULL </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 on success, or a LIBUSB_ERROR code on failure </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="ga6deff4c7d3a6c04bb9ec9fd259b48933"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_handle_events_timeout </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct timeval * </td> <td class="paramname"><em>tv</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Handle any pending events. </p> <p>Like <a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b" title="Handle any pending events. ">libusb_handle_events_timeout_completed()</a>, but without the completed parameter, calling this function is equivalent to calling <a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b" title="Handle any pending events. ">libusb_handle_events_timeout_completed()</a> with a NULL completed parameter.</p> <p>This function is kept primarily for backwards compatibility. All new code should call <a class="el" href="group__poll.html#ga0bc99f39e4cf5ad393cd5936c36037d1" title="Handle any pending events in blocking mode. ">libusb_handle_events_completed()</a> or <a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b" title="Handle any pending events. ">libusb_handle_events_timeout_completed()</a> to avoid race conditions.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">tv</td><td>the maximum time to block waiting for events, or an all zero timeval struct for non-blocking mode </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 on success, or a LIBUSB_ERROR code on failure </dd></dl> </div> </div> <a class="anchor" id="ga4989086e3f0327f3886a4c474ec7c327"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_handle_events </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Handle any pending events in blocking mode. </p> <p>There is currently a timeout hardcoded at 60 seconds but we plan to make it unlimited in future. For finer control over whether this function is blocking or non-blocking, or for control over the timeout, use <a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b" title="Handle any pending events. ">libusb_handle_events_timeout_completed()</a> instead.</p> <p>This function is kept primarily for backwards compatibility. All new code should call <a class="el" href="group__poll.html#ga0bc99f39e4cf5ad393cd5936c36037d1" title="Handle any pending events in blocking mode. ">libusb_handle_events_completed()</a> or <a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b" title="Handle any pending events. ">libusb_handle_events_timeout_completed()</a> to avoid race conditions.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 on success, or a LIBUSB_ERROR code on failure </dd></dl> </div> </div> <a class="anchor" id="ga0bc99f39e4cf5ad393cd5936c36037d1"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_handle_events_completed </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">int * </td> <td class="paramname"><em>completed</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Handle any pending events in blocking mode. </p> <p>Like <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a>, with the addition of a completed parameter to allow for race free waiting for the completion of a specific transfer.</p> <p>See <a class="el" href="group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b" title="Handle any pending events. ">libusb_handle_events_timeout_completed()</a> for details on the completed parameter.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">completed</td><td>pointer to completion integer to check, or NULL </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 on success, or a LIBUSB_ERROR code on failure </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="ga71da081f97afa3bf68aed8e372254e8f"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_handle_events_locked </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct timeval * </td> <td class="paramname"><em>tv</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Handle any pending events by polling file descriptors, without checking if any other threads are already doing so. </p> <p>Must be called with the event lock held, see <a class="el" href="group__poll.html#gaa72153938dc4f34decfacbc6cc6237ef" title="Acquire the event handling lock, blocking until successful acquisition if it is contended. ">libusb_lock_events()</a>.</p> <p>This function is designed to be called under the situation where you have taken the event lock and are calling poll()/select() directly on libusbx's file descriptors (as opposed to using <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a> or similar). You detect events on libusbx's descriptors, so you then call this function with a zero timeout value (while still holding the event lock).</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">tv</td><td>the maximum time to block waiting for events, or zero for non-blocking mode </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 on success, or a LIBUSB_ERROR code on failure </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl> </div> </div> <a class="anchor" id="gae7a654315636bebf404c1784429f06df"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_pollfds_handle_timeouts </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Determines whether your application must apply special timing considerations when monitoring libusbx's file descriptors. </p> <p>This function is only useful for applications which retrieve and poll libusbx's file descriptors in their own main loop (<a class="el" href="group__poll.html#pollmain">The more advanced option</a>).</p> <p>Ordinarily, libusbx's event handler needs to be called into at specific moments in time (in addition to times when there is activity on the file descriptor set). The usual approach is to use <a class="el" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634" title="Determine the next internal timeout that libusbx needs to handle. ">libusb_get_next_timeout()</a> to learn about when the next timeout occurs, and to adjust your poll()/select() timeout accordingly so that you can make a call into the library at that time.</p> <p>Some platforms supported by libusbx do not come with this baggage - any events relevant to timing will be represented by activity on the file descriptor set, and <a class="el" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634" title="Determine the next internal timeout that libusbx needs to handle. ">libusb_get_next_timeout()</a> will always return 0. This function allows you to detect whether you are running on such a platform.</p> <p>Since v1.0.5.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 if you must call into libusbx at times determined by <a class="el" href="group__poll.html#ga5bc6f5bc71a43845244912da6679f634" title="Determine the next internal timeout that libusbx needs to handle. ">libusb_get_next_timeout()</a>, or 1 if all timeout events are handled internally or through regular activity on the file descriptors. </dd></dl> <dl class="section see"><dt>See Also</dt><dd><a class="el" href="group__poll.html#pollmain">Polling libusbx file descriptors for event handling</a> </dd></dl> </div> </div> <a class="anchor" id="ga5bc6f5bc71a43845244912da6679f634"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">int libusb_get_next_timeout </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">struct timeval * </td> <td class="paramname"><em>tv</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Determine the next internal timeout that libusbx needs to handle. </p> <p>You only need to use this function if you are calling poll() or select() or similar on libusbx's file descriptors yourself - you do not need to use it if you are calling <a class="el" href="group__poll.html#ga4989086e3f0327f3886a4c474ec7c327" title="Handle any pending events in blocking mode. ">libusb_handle_events()</a> or a variant directly.</p> <p>You should call this function in your main loop in order to determine how long to wait for select() or poll() to return results. libusbx needs to be called into at this timeout, so you should use it as an upper bound on your select() or poll() call.</p> <p>When the timeout has expired, call into <a class="el" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933" title="Handle any pending events. ">libusb_handle_events_timeout()</a> (perhaps in non-blocking mode) so that libusbx can handle the timeout.</p> <p>This function may return 1 (success) and an all-zero timeval. If this is the case, it indicates that libusbx has a timeout that has already expired so you should call <a class="el" href="group__poll.html#ga6deff4c7d3a6c04bb9ec9fd259b48933" title="Handle any pending events. ">libusb_handle_events_timeout()</a> or similar immediately. A return code of 0 indicates that there are no pending timeouts.</p> <p>On some platforms, this function will always returns 0 (no pending timeouts). See <a class="el" href="group__poll.html#polltime">Notes on time-based events</a>.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">tv</td><td>output location for a relative time against the current clock in which libusbx must be called into in order to process timeout events </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>0 if there are no pending timeouts, 1 if a timeout was returned, or LIBUSB_ERROR_OTHER on failure </dd></dl> </div> </div> <a class="anchor" id="ga1b7b2deb193f2e9ffda5e727361d7e67"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">void libusb_set_pollfd_notifiers </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="group__poll.html#gace4a3cb954fbc69c43b734fe2202f027">libusb_pollfd_added_cb</a> </td> <td class="paramname"><em>added_cb</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="group__poll.html#ga91a1f6a5fe01484cb308913a5e2b38e1">libusb_pollfd_removed_cb</a> </td> <td class="paramname"><em>removed_cb</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">void * </td> <td class="paramname"><em>user_data</em> </td> </tr> <tr> <td></td> <td>)</td> <td></td><td></td> </tr> </table> </div><div class="memdoc"> <p>Register notification functions for file descriptor additions/removals. </p> <p>These functions will be invoked for every new or removed file descriptor that libusbx uses as an event source.</p> <p>To remove notifiers, pass NULL values for the function pointers.</p> <p>Note that file descriptors may have been added even before you register these notifiers (e.g. at <a class="el" href="group__lib.html#ga9517c37281bba0b51cc62eba728be48b" title="Initialize libusb. ">libusb_init()</a> time).</p> <p>Additionally, note that the removal notifier may be called during <a class="el" href="group__lib.html#ga86532f222d4f1332a5f8f5eef9a92da9" title="Deinitialize libusb. ">libusb_exit()</a> (e.g. when it is closing file descriptors that were opened and added to the poll set at <a class="el" href="group__lib.html#ga9517c37281bba0b51cc62eba728be48b" title="Initialize libusb. ">libusb_init()</a> time). If you don't want this, remove the notifiers immediately before calling <a class="el" href="group__lib.html#ga86532f222d4f1332a5f8f5eef9a92da9" title="Deinitialize libusb. ">libusb_exit()</a>.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> <tr><td class="paramname">added_cb</td><td>pointer to function for addition notifications </td></tr> <tr><td class="paramname">removed_cb</td><td>pointer to function for removal notifications </td></tr> <tr><td class="paramname">user_data</td><td>User data to be passed back to callbacks (useful for passing context information) </td></tr> </table> </dd> </dl> </div> </div> <a class="anchor" id="gab1a72869a926552b27a6c667695df3a2"></a> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> <td class="memname">struct <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a>** libusb_get_pollfds </td> <td>(</td> <td class="paramtype"><a class="el" href="group__lib.html#ga4ec088aa7b79c4a9599e39bf36a72833">libusb_context</a> * </td> <td class="paramname"><em>ctx</em></td><td>)</td> <td></td> </tr> </table> </div><div class="memdoc"> <p>Retrieve a list of file descriptors that should be polled by your main loop as libusbx event sources. </p> <p>The returned list is NULL-terminated and should be freed with free() when done. The actual list contents must not be touched.</p> <p>As file descriptors are a Unix-specific concept, this function is not available on Windows and will always return NULL.</p> <dl class="params"><dt>Parameters</dt><dd> <table class="params"> <tr><td class="paramname">ctx</td><td>the context to operate on, or NULL for the default context </td></tr> </table> </dd> </dl> <dl class="section return"><dt>Returns</dt><dd>a NULL-terminated list of <a class="el" href="structlibusb__pollfd.html" title="File descriptor for polling. ">libusb_pollfd</a> structures </dd> <dd> NULL on error </dd> <dd> NULL on platforms where the functionality is not available </dd></dl> </div> </div> </div><!-- contents --> <!-- start footer part --> <hr class="footer"/><address class="footer"><small> Generated on Sat Oct 19 2013 16:44:34 by  <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/> </a> 1.8.5 </small></address> </body> </html>