diff options
Diffstat (limited to 'wifi/1.2/default/THREADING.README')
-rw-r--r-- | wifi/1.2/default/THREADING.README | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/wifi/1.2/default/THREADING.README b/wifi/1.2/default/THREADING.README new file mode 100644 index 00000000..8366ca02 --- /dev/null +++ b/wifi/1.2/default/THREADING.README | |||
@@ -0,0 +1,35 @@ | |||
1 | Vendor HAL Threading Model | ||
2 | ========================== | ||
3 | The vendor HAL service has two threads: | ||
4 | 1. HIDL thread: This is the main thread which processes all the incoming HIDL | ||
5 | RPC's. | ||
6 | 2. Legacy HAL event loop thread: This is the thread forked off for processing | ||
7 | the legacy HAL event loop (wifi_event_loop()). This thread is used to process | ||
8 | any asynchronous netlink events posted by the driver. Any asynchronous | ||
9 | callbacks passed to the legacy HAL API's are invoked on this thread. | ||
10 | |||
11 | Synchronization Concerns | ||
12 | ======================== | ||
13 | wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the | ||
14 | legacy callbacks. Each of these "C" style function invokes a corresponding | ||
15 | "std::function" version of the callback which does the actual processing. | ||
16 | The variables holding these "std::function" callbacks are reset from the HIDL | ||
17 | thread when they are no longer used. For example: stopGscan() will reset the | ||
18 | corresponding "on_gscan_*" callback variables which were set when startGscan() | ||
19 | was invoked. This is not thread safe since these callback variables are | ||
20 | accesed from the legacy hal event loop thread as well. | ||
21 | |||
22 | Synchronization Solution | ||
23 | ======================== | ||
24 | Adding a global lock seems to be the most trivial solution to the problem. | ||
25 | a) All of the asynchronous "C" style callbacks will acquire the global lock | ||
26 | before invoking the corresponding "std::function" callback variables. | ||
27 | b) All of the HIDL methods will also acquire the global lock before processing | ||
28 | (in hidl_return_util::validateAndCall()). | ||
29 | |||
30 | Note: It's important that we only acquire the global lock for asynchronous | ||
31 | callbacks, because there is no guarantee (or documentation to clarify) that the | ||
32 | synchronous callbacks are invoked on the same invocation thread. If that is not | ||
33 | the case in some implementation, we will end up deadlocking the system since the | ||
34 | HIDL thread would have acquired the global lock which is needed by the | ||
35 | synchronous callback executed on the legacy hal event loop thread. | ||