File: README.multi-thread

package info (click to toggle)
usbredir 0.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 1,884 kB
  • sloc: ansic: 5,412; sh: 4,177; makefile: 52
file content (74 lines) | stat: -rw-r--r-- 2,902 bytes parent folder | download | duplicates (3)
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
libusbredirparser and libusbredirhost are *not* 100% thread-safe. They allow
usage from multiple threads, but with limitations.

The intended usage of the multi-threading support for libusbredirparser is to
have one reader thread and allow writes / packet sends from multiple threads
(including the reader thread). It is up to the app to deal with flushing
writes by calling do_write itself. do_write may be called from multiple
threads, libusbredirparser will serialize any calls to the write callback.

The intended usage of the multi-threading support for libusbredirhost is to
have one reader thread, one thread calling libusb's handle_events function
and optionally also a separate writer thread.

libusbredirhost offers setting a write flush callback, which it will call
(if set) everytime it has queued some data to write. This can be used to
wakeup a writer thread or it can call usbredirhost_write_guest_data, to
directly write out the queued data from the context of its caller. Note that
the flush callback may be called from both usbredirparser_do_read as well
as from libusb_handle_events, so if those are done in separate threads,
it may get called from multiple threads!!


The above translates to some functions only allowing one caller at a time,
while others allow multiple callers, see below for a detailed overview.

In order to enable the multi-thread support in libusbredir* the app
must provide a number of locking callback functions, for libusbredirparser
this is done by filling in the usbredirparser_*_lock funcs in the
usbredirparser struct before calling usbredirparser_init(). For
libusbredirhost the locking functions (and a write-flush callback) can
be specified by using usbredirhost_open_full() instead of
usbredirhost_open().

Note that the alloc_lock_func may not fail! If it returns NULL no locking
will be done and usage from multiple threads will be unsafe.


Overview of per function multi-thread safeness
----------------------------------------------

usbredirparser:
-Only one caller allowed at a time:
 usbredirparser_create
 usbredirparser_init
 usbredirparser_destroy
 usbredirparser_do_read

-Multiple callers allowed:
 usbredirparser_get_peer_caps (1)
 usbredirparser_peer_has_cap (1)
 usbredirparser_has_data_to_write
 usbredirparser_do_write
 usbredirparser_free_write_buffer
 usbredirparser_free_packet_data
 usbredirparser_send_*

usbredirhost:
-Only one caller allowed at a time:
 usbredirhost_open
 usbredirhost_open_full
 usbredirhost_close
 usbredirhost_read_guest_data
 usbredirhost_set_device

-Multiple callers allowed:
 usbredirhost_has_data_to_write
 usbredirhost_write_guest_data
 usbredirhost_free_write_buffer
 libusb_handle_events (2)

(1) These only return the actual peer caps after the initial hello message
    has been read, as indicated by the hello_func callback.

(2) libusb is thread safe itself, thus allowing multiple callers.