-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgroup__libusb__poll.html
More file actions
856 lines (812 loc) · 66.4 KB
/
group__libusb__poll.html
File metadata and controls
856 lines (812 loc) · 66.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
<!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.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>libusb-1.0: 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="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.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 id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">libusb-1.0
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="summary">
<a href="#nested-classes">Classes</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">
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
Classes</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="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:ga291d7463aefd0de6209b537db4d06e70"><td class="memItemLeft" align="right" valign="top">typedef <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a>(<a class="el" href="group__libusb__misc.html#gaa7d6035eb2692d455d27144560a0f68d">LIBUSB_CALL</a> * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga291d7463aefd0de6209b537db4d06e70">libusb_pollfd_added_cb</a>) (int fd, short events, <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> *user_data)</td></tr>
<tr class="separator:ga291d7463aefd0de6209b537db4d06e70"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:gabff1d67f33725c93ef6dff699335c225"><td class="memItemLeft" align="right" valign="top">typedef <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a>(<a class="el" href="group__libusb__misc.html#gaa7d6035eb2692d455d27144560a0f68d">LIBUSB_CALL</a> * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#gabff1d67f33725c93ef6dff699335c225">libusb_pollfd_removed_cb</a>) (int fd, <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> *user_data)</td></tr>
<tr class="separator:gabff1d67f33725c93ef6dff699335c225"><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:ga81cc7c2bc30407c59b7e734c7550f8b2"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga81cc7c2bc30407c59b7e734c7550f8b2">libusb_try_lock_events</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga81cc7c2bc30407c59b7e734c7550f8b2"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga3fe966580b283e1efc91c7e11bae0c89"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga3fe966580b283e1efc91c7e11bae0c89">libusb_lock_events</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga3fe966580b283e1efc91c7e11bae0c89"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:gadb8f5d4fb12b340f40b0bed841fe5fa0"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#gadb8f5d4fb12b340f40b0bed841fe5fa0">libusb_unlock_events</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:gadb8f5d4fb12b340f40b0bed841fe5fa0"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:gaff8a999713883242aebec53fd8fda288"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#gaff8a999713883242aebec53fd8fda288">libusb_event_handling_ok</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:gaff8a999713883242aebec53fd8fda288"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga448517e64d5b326944432ab773b8262f"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga448517e64d5b326944432ab773b8262f">libusb_event_handler_active</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga448517e64d5b326944432ab773b8262f"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga303fa5e888f09162e59aef14d51942a4"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga303fa5e888f09162e59aef14d51942a4">libusb_interrupt_event_handler</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga303fa5e888f09162e59aef14d51942a4"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga42414148fd511c5af8cc65cc0daf504a"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga42414148fd511c5af8cc65cc0daf504a">libusb_lock_event_waiters</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga42414148fd511c5af8cc65cc0daf504a"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:gacbf0f55ba01600dee3c3d78dc27f495d"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#gacbf0f55ba01600dee3c3d78dc27f495d">libusb_unlock_event_waiters</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:gacbf0f55ba01600dee3c3d78dc27f495d"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga24bcd0e269101fdbd00ecd38602bc2c1"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga24bcd0e269101fdbd00ecd38602bc2c1">libusb_wait_for_event</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, struct timeval *tv)</td></tr>
<tr class="separator:ga24bcd0e269101fdbd00ecd38602bc2c1"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga45948958630109e2969221f845f58fbd"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga45948958630109e2969221f845f58fbd">libusb_handle_events_timeout_completed</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, struct timeval *tv, int *completed)</td></tr>
<tr class="separator:ga45948958630109e2969221f845f58fbd"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:gae74724dd975e6eb49bb8e93640c126dd"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">libusb_handle_events_timeout</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, struct timeval *tv)</td></tr>
<tr class="separator:gae74724dd975e6eb49bb8e93640c126dd"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:gae51897021354eae052a382e814a587ba"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#gae51897021354eae052a382e814a587ba">libusb_handle_events</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:gae51897021354eae052a382e814a587ba"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga166cee6b958a10ec2c43055c97505d38"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga166cee6b958a10ec2c43055c97505d38">libusb_handle_events_completed</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, int *completed)</td></tr>
<tr class="separator:ga166cee6b958a10ec2c43055c97505d38"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga06ee3999a05c494d0aad084d052e5774"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga06ee3999a05c494d0aad084d052e5774">libusb_handle_events_locked</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, struct timeval *tv)</td></tr>
<tr class="separator:ga06ee3999a05c494d0aad084d052e5774"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga683eb812bf755bf67af8d226c21d5e42"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga683eb812bf755bf67af8d226c21d5e42">libusb_pollfds_handle_timeouts</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga683eb812bf755bf67af8d226c21d5e42"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga7d35496be9deea4898e621aacb2c4cd6"><td class="memItemLeft" align="right" valign="top">int API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">libusb_get_next_timeout</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, struct timeval *tv)</td></tr>
<tr class="separator:ga7d35496be9deea4898e621aacb2c4cd6"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga11aa9845c618f1441709158643176197"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga11aa9845c618f1441709158643176197">libusb_set_pollfd_notifiers</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx, <a class="el" href="group__libusb__poll.html#ga291d7463aefd0de6209b537db4d06e70">libusb_pollfd_added_cb</a> added_cb, <a class="el" href="group__libusb__poll.html#gabff1d67f33725c93ef6dff699335c225">libusb_pollfd_removed_cb</a> removed_cb, <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> *user_data)</td></tr>
<tr class="separator:ga11aa9845c618f1441709158643176197"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga2442bd57b7aaca1fd971cf602eaa0125"><td class="memItemLeft" align="right" valign="top">DEFAULT_VISIBILITY const struct <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> **<a class="el" href="group__libusb__misc.html#gaa7d6035eb2692d455d27144560a0f68d">LIBUSB_CALL</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga2442bd57b7aaca1fd971cf602eaa0125">libusb_get_pollfds</a> (<a class="el" href="structlibusb__context.html">libusb_context</a> *ctx)</td></tr>
<tr class="separator:ga2442bd57b7aaca1fd971cf602eaa0125"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ga4d49e70f3e789ee259356e2b2621c2ed"><td class="memItemLeft" align="right" valign="top"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED </td><td class="memItemRight" valign="bottom"><a class="el" href="group__libusb__poll.html#ga4d49e70f3e789ee259356e2b2621c2ed">libusb_free_pollfds</a> (const struct <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> **pollfds)</td></tr>
<tr class="separator:ga4d49e70f3e789ee259356e2b2621c2ed"><td class="memSeparator" colspan="2"> </td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<p>This page documents libusb's functions for polling events and timing. These functions are only necessary for users of the <a class="el" href="group__libusb__asyncio.html">asynchronous API</a>. If you are only using the simpler <a class="el" href="group__libusb__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__libusb__asyncio.html#asyncevent">event handling</a> section of the asynchronous API documentation. In summary, libusb does not create internal threads for event processing and hence relies on your application calling into libusb 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 libusb'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__libusb__poll.html#gae51897021354eae052a382e814a587ba">libusb_handle_events()</a>.</p>
<p>There is one final event handling complication. libusb 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 libusb is called into at or after the timeout to handle it. So, in addition to considering libusb's file descriptors in your main event loop, you must also consider that libusb 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__libusb__poll.html#polltime">Notes on time-based events</a> details.</p>
<p>In order to know precisely when libusb needs to be called into, libusb 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 libusb 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 libusb</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__libusb__poll.html#gae51897021354eae052a382e814a587ba">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__libusb__poll.html#gae51897021354eae052a382e814a587ba">libusb_handle_events()</a> will handle those details internally.</p>
<h1><a class="anchor" id="libusb_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__libusb__poll.html#ga2442bd57b7aaca1fd971cf602eaa0125">libusb_get_pollfds()</a> simply returns NULL. Applications which want to support Windows are advised to use an <a class="el" href="group__libusb__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, libusb 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 libusb and monitor those too. When you detect activity on libusb's file descriptors, you call <a class="el" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">libusb_handle_events_timeout()</a> in non-blocking mode.</p>
<p>What's more, libusb 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__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">libusb_get_next_timeout()</a>), and then it needs to call <a class="el" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">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>libusb 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 libusb 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 libusb</span></div><div class="line"></div><div class="line"><a class="code" href="group__libusb__poll.html#ga2442bd57b7aaca1fd971cf602eaa0125">libusb_get_pollfds</a>(ctx)</div><div class="line"><span class="keywordflow">while</span> (user has not requested application exit) {</div><div class="line"> <a class="code" href="group__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">libusb_get_next_timeout</a>(ctx);</div><div class="line"> poll(on libusb 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 libusb just suggested)</div><div class="line"> <span class="keywordflow">if</span> (poll() indicated activity on libusb file descriptors)</div><div class="line"> <a class="code" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">libusb_handle_events_timeout</a>(ctx, &zero_tv);</div><div class="line"> <span class="keywordflow">if</span> (time has elapsed to or beyond the libusb <a class="code" href="structlibusb__transfer.html#a9a12af15ca5b482f5dcaebd26a848cbb">timeout</a>)</div><div class="line"> <a class="code" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">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 libusb 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>libusb v1.0.5 or newer</li>
</ul>
</li>
</ul>
<p>Under these configurations, <a class="el" href="group__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">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 libusb</span></div><div class="line"></div><div class="line"><a class="code" href="group__libusb__poll.html#ga2442bd57b7aaca1fd971cf602eaa0125">libusb_get_pollfds</a>(ctx)</div><div class="line"><span class="keywordflow">while</span> (user has not requested application exit) {</div><div class="line"> poll(on libusb 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 libusb file descriptors)</div><div class="line"> <a class="code" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">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 libusb 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__libusb__poll.html#ga683eb812bf755bf67af8d226c21d5e42">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 libusb's next timeout in your main loop, then you are advised to check the return value of <a class="el" href="group__libusb__poll.html#ga683eb812bf755bf67af8d226c21d5e42">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 libusb uses as event sources may change during the life of your application. Rather than having to repeatedly call <a class="el" href="group__libusb__poll.html#ga2442bd57b7aaca1fd971cf602eaa0125">libusb_get_pollfds()</a>, you can set up notification functions for when the file descriptor set changes using <a class="el" href="group__libusb__poll.html#ga11aa9845c618f1441709158643176197">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__libusb__poll.html#ga06ee3999a05c494d0aad084d052e5774">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="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </p>
<h2 class="groupheader">Typedef Documentation</h2>
<a id="ga291d7463aefd0de6209b537db4d06e70"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga291d7463aefd0de6209b537db4d06e70">◆ </a></span>libusb_pollfd_added_cb</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">typedef <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a>(<a class="el" href="group__libusb__misc.html#gaa7d6035eb2692d455d27144560a0f68d">LIBUSB_CALL</a> * libusb_pollfd_added_cb) (int fd, short events, <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> *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__libusb__poll.html#ga11aa9845c618f1441709158643176197">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__libusb__poll.html#ga11aa9845c618f1441709158643176197">libusb_set_pollfd_notifiers()</a> </dd></dl>
</div>
</div>
<a id="gabff1d67f33725c93ef6dff699335c225"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gabff1d67f33725c93ef6dff699335c225">◆ </a></span>libusb_pollfd_removed_cb</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">typedef <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a>(<a class="el" href="group__libusb__misc.html#gaa7d6035eb2692d455d27144560a0f68d">LIBUSB_CALL</a> * libusb_pollfd_removed_cb) (int fd, <a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> *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. 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__libusb__poll.html#ga11aa9845c618f1441709158643176197">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__libusb__poll.html#ga11aa9845c618f1441709158643176197">libusb_set_pollfd_notifiers()</a> </dd></dl>
</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="ga448517e64d5b326944432ab773b8262f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga448517e64d5b326944432ab773b8262f">◆ </a></span>libusb_event_handler_active()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_event_handler_active </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. 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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl>
</div>
</div>
<a id="gaff8a999713883242aebec53fd8fda288"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gaff8a999713883242aebec53fd8fda288">◆ </a></span>libusb_event_handling_ok()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_event_handling_ok </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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, libusb 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="libusb_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 <a class="el" href="libusb_mtasync.html#fullstory">Multi-threaded I/O: the full story</a> </dd></dl>
</div>
</div>
<a id="ga4d49e70f3e789ee259356e2b2621c2ed"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga4d49e70f3e789ee259356e2b2621c2ed">◆ </a></span>libusb_free_pollfds()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_free_pollfds </td>
<td>(</td>
<td class="paramtype">const struct <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> ** </td>
<td class="paramname"><em>pollfds</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Free a list of <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> structures. This should be called for all pollfd lists allocated with <a class="el" href="group__libusb__poll.html#ga2442bd57b7aaca1fd971cf602eaa0125">libusb_get_pollfds()</a>.</p>
<p>Since version 1.0.20, <a class="el" href="group__libusb__misc.html#gaabe4bc36a83358685d36a6c853cbb4de">LIBUSB_API_VERSION</a> >= 0x01000104</p>
<p>It is legal to call this function with a NULL pollfd list. In this case, the function will simply do nothing.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">pollfds</td><td>the list of <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a> structures to free </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="ga7d35496be9deea4898e621aacb2c4cd6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga7d35496be9deea4898e621aacb2c4cd6">◆ </a></span>libusb_get_next_timeout()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_get_next_timeout </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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 libusb needs to handle. You only need to use this function if you are calling poll() or select() or similar on libusb's file descriptors yourself - you do not need to use it if you are calling <a class="el" href="group__libusb__poll.html#gae51897021354eae052a382e814a587ba">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. libusb 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__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">libusb_handle_events_timeout()</a> (perhaps in non-blocking mode) so that libusb 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 libusb has a timeout that has already expired so you should call <a class="el" href="group__libusb__poll.html#gae74724dd975e6eb49bb8e93640c126dd">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__libusb__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 libusb 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 id="ga2442bd57b7aaca1fd971cf602eaa0125"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga2442bd57b7aaca1fd971cf602eaa0125">◆ </a></span>libusb_get_pollfds()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">DEFAULT_VISIBILITY const struct <a class="el" href="structlibusb__pollfd.html">libusb_pollfd</a>** <a class="el" href="group__libusb__misc.html#gaa7d6035eb2692d455d27144560a0f68d">LIBUSB_CALL</a> libusb_get_pollfds </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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 libusb event sources.</p>
<p>The returned list is NULL-terminated and should be freed with <a class="el" href="group__libusb__poll.html#ga4d49e70f3e789ee259356e2b2621c2ed">libusb_free_pollfds()</a> 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">libusb_pollfd</a> structures </dd>
<dd>
NULL on error </dd>
<dd>
NULL on platforms where the functionality is not available </dd></dl>
</div>
</div>
<a id="gae51897021354eae052a382e814a587ba"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gae51897021354eae052a382e814a587ba">◆ </a></span>libusb_handle_events()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_handle_events </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. There is currently a timeout hard-coded 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__libusb__poll.html#ga45948958630109e2969221f845f58fbd">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__libusb__poll.html#ga166cee6b958a10ec2c43055c97505d38">libusb_handle_events_completed()</a> or <a class="el" href="group__libusb__poll.html#ga45948958630109e2969221f845f58fbd">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 id="ga166cee6b958a10ec2c43055c97505d38"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga166cee6b958a10ec2c43055c97505d38">◆ </a></span>libusb_handle_events_completed()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_handle_events_completed </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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__libusb__poll.html#gae51897021354eae052a382e814a587ba">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__libusb__poll.html#ga45948958630109e2969221f845f58fbd">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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl>
</div>
</div>
<a id="ga06ee3999a05c494d0aad084d052e5774"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga06ee3999a05c494d0aad084d052e5774">◆ </a></span>libusb_handle_events_locked()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_handle_events_locked </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. Must be called with the event lock held, see <a class="el" href="group__libusb__poll.html#ga3fe966580b283e1efc91c7e11bae0c89">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 libusb's file descriptors (as opposed to using <a class="el" href="group__libusb__poll.html#gae51897021354eae052a382e814a587ba">libusb_handle_events()</a> or similar). You detect events on libusb'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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl>
</div>
</div>
<a id="gae74724dd975e6eb49bb8e93640c126dd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gae74724dd975e6eb49bb8e93640c126dd">◆ </a></span>libusb_handle_events_timeout()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_handle_events_timeout </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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__libusb__poll.html#ga45948958630109e2969221f845f58fbd">libusb_handle_events_timeout_completed()</a>, but without the completed parameter, calling this function is equivalent to calling <a class="el" href="group__libusb__poll.html#ga45948958630109e2969221f845f58fbd">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__libusb__poll.html#ga166cee6b958a10ec2c43055c97505d38">libusb_handle_events_completed()</a> or <a class="el" href="group__libusb__poll.html#ga45948958630109e2969221f845f58fbd">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 id="ga45948958630109e2969221f845f58fbd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga45948958630109e2969221f845f58fbd">◆ </a></span>libusb_handle_events_timeout_completed()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_handle_events_timeout_completed </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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>libusb 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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl>
</div>
</div>
<a id="ga303fa5e888f09162e59aef14d51942a4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga303fa5e888f09162e59aef14d51942a4">◆ </a></span>libusb_interrupt_event_handler()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_interrupt_event_handler </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">libusb_context</a> * </td>
<td class="paramname"><em>ctx</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Interrupt any active thread that is handling events. This is mainly useful for interrupting a dedicated event handling thread when an application wishes to call <a class="el" href="group__libusb__lib.html#gab57b6d0abf8349a24792f12b53d20220">libusb_exit()</a>.</p>
<p>Since version 1.0.21, <a class="el" href="group__libusb__misc.html#gaabe4bc36a83358685d36a6c853cbb4de">LIBUSB_API_VERSION</a> >= 0x01000105</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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="ga42414148fd511c5af8cc65cc0daf504a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga42414148fd511c5af8cc65cc0daf504a">◆ </a></span>libusb_lock_event_waiters()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_lock_event_waiters </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. 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__libusb__poll.html#gae51897021354eae052a382e814a587ba">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__libusb__poll.html#ga24bcd0e269101fdbd00ecd38602bc2c1">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 libusb's file descriptors directly, <b>and</b> may potentially be handling events from 2 threads simultaneously. If you stick to libusb's event handling loop functions (e.g. <a class="el" href="group__libusb__poll.html#gae51897021354eae052a382e814a587ba">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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="ga3fe966580b283e1efc91c7e11bae0c89"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga3fe966580b283e1efc91c7e11bae0c89">◆ </a></span>libusb_lock_events()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_lock_events </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. This lock is used to ensure that only one thread is monitoring libusb 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 libusb's file descriptors directly. If you stick to libusb's event handling loop functions (e.g. <a class="el" href="group__libusb__poll.html#gae51897021354eae052a382e814a587ba">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__libusb__poll.html#gadb8f5d4fb12b340f40b0bed841fe5fa0">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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="ga683eb812bf755bf67af8d226c21d5e42"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga683eb812bf755bf67af8d226c21d5e42">◆ </a></span>libusb_pollfds_handle_timeouts()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_pollfds_handle_timeouts </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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 libusb's file descriptors.</p>
<p>This function is only useful for applications which retrieve and poll libusb's file descriptors in their own main loop (<a class="el" href="group__libusb__poll.html#libusb_pollmain">The more advanced option</a>).</p>
<p>Ordinarily, libusb'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__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">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 libusb 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__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">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 libusb at times determined by <a class="el" href="group__libusb__poll.html#ga7d35496be9deea4898e621aacb2c4cd6">libusb_get_next_timeout()</a>, or 1 if all timeout events are handled internally or through regular activity on the file descriptors. <a class="el" href="group__libusb__poll.html#libusb_pollmain">Polling libusb file descriptors for event handling</a> </dd></dl>
</div>
</div>
<a id="ga11aa9845c618f1441709158643176197"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga11aa9845c618f1441709158643176197">◆ </a></span>libusb_set_pollfd_notifiers()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_set_pollfd_notifiers </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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__libusb__poll.html#ga291d7463aefd0de6209b537db4d06e70">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__libusb__poll.html#gabff1d67f33725c93ef6dff699335c225">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"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> * </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. These functions will be invoked for every new or removed file descriptor that libusb 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__libusb__lib.html#ga297006e15c446cee88ab09b02f1bbe0c">libusb_init()</a> time).</p>
<p>Additionally, note that the removal notifier may be called during <a class="el" href="group__libusb__lib.html#gab57b6d0abf8349a24792f12b53d20220">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__libusb__lib.html#ga297006e15c446cee88ab09b02f1bbe0c">libusb_init()</a> time). If you don't want this, remove the notifiers immediately before calling <a class="el" href="group__libusb__lib.html#gab57b6d0abf8349a24792f12b53d20220">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 id="ga81cc7c2bc30407c59b7e734c7550f8b2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga81cc7c2bc30407c59b7e734c7550f8b2">◆ </a></span>libusb_try_lock_events()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_try_lock_events </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. This lock is used to ensure that only one thread is monitoring libusb 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 libusb's file descriptors directly. If you stick to libusb's event handling loop functions (e.g. <a class="el" href="group__libusb__poll.html#gae51897021354eae052a382e814a587ba">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__libusb__poll.html#gadb8f5d4fb12b340f40b0bed841fe5fa0">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) <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl>
</div>
</div>
<a id="gacbf0f55ba01600dee3c3d78dc27f495d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gacbf0f55ba01600dee3c3d78dc27f495d">◆ </a></span>libusb_unlock_event_waiters()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_unlock_event_waiters </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="gadb8f5d4fb12b340f40b0bed841fe5fa0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#gadb8f5d4fb12b340f40b0bed841fe5fa0">◆ </a></span>libusb_unlock_events()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="group__libusb__asyncio.html#ga8ca3594d1761da8da91be2851f4e8f21">void</a> API_EXPORTED libusb_unlock_events </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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__libusb__poll.html#ga81cc7c2bc30407c59b7e734c7550f8b2">libusb_try_lock_events()</a> or <a class="el" href="group__libusb__poll.html#ga3fe966580b283e1efc91c7e11bae0c89">libusb_lock_events()</a>. Releasing this lock will wake up any threads blocked on <a class="el" href="group__libusb__poll.html#ga24bcd0e269101fdbd00ecd38602bc2c1">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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a id="ga24bcd0e269101fdbd00ecd38602bc2c1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ga24bcd0e269101fdbd00ecd38602bc2c1">◆ </a></span>libusb_wait_for_event()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int API_EXPORTED libusb_wait_for_event </td>
<td>(</td>
<td class="paramtype"><a class="el" href="structlibusb__context.html">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. Must be called with the event waiters lock held, see <a class="el" href="group__libusb__poll.html#ga42414148fd511c5af8cc65cc0daf504a">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__libusb__poll.html#gadb8f5d4fb12b340f40b0bed841fe5fa0">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 <a class="el" href="libusb_mtasync.html">Multi-threaded applications and asynchronous I/O</a> </dd></dl>
</div>
</div>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by  <a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>