Roshan Pius | 091e1c1 | 2017-01-30 16:40:50 -0800 | [diff] [blame] | 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. |