xref: /aosp_15_r20/hardware/interfaces/wifi/aidl/default/THREADING.README (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard WorkerVendor HAL Threading Model
2*4d7e907cSAndroid Build Coastguard Worker==========================
3*4d7e907cSAndroid Build Coastguard WorkerThe vendor HAL service has two threads:
4*4d7e907cSAndroid Build Coastguard Worker1. AIDL thread: This is the main thread which processes all the incoming AIDL
5*4d7e907cSAndroid Build Coastguard WorkerRPC's.
6*4d7e907cSAndroid Build Coastguard Worker2. Legacy HAL event loop thread: This is the thread forked off for processing
7*4d7e907cSAndroid Build Coastguard Workerthe legacy HAL event loop (wifi_event_loop()). This thread is used to process
8*4d7e907cSAndroid Build Coastguard Workerany asynchronous netlink events posted by the driver. Any asynchronous
9*4d7e907cSAndroid Build Coastguard Workercallbacks passed to the legacy HAL API's are invoked on this thread.
10*4d7e907cSAndroid Build Coastguard Worker
11*4d7e907cSAndroid Build Coastguard WorkerSynchronization Concerns
12*4d7e907cSAndroid Build Coastguard Worker========================
13*4d7e907cSAndroid Build Coastguard Workerwifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the
14*4d7e907cSAndroid Build Coastguard Workerlegacy callbacks. Each of these "C" style functions invokes a corresponding
15*4d7e907cSAndroid Build Coastguard Worker"std::function" version of the callback which does the actual processing.
16*4d7e907cSAndroid Build Coastguard WorkerThe variables holding these "std::function" callbacks are reset from the AIDL
17*4d7e907cSAndroid Build Coastguard Workerthread when they are no longer used. For example: stopGscan() will reset the
18*4d7e907cSAndroid Build Coastguard Workercorresponding "on_gscan_*" callback variables which were set when startGscan()
19*4d7e907cSAndroid Build Coastguard Workerwas invoked. This is not thread safe since these callback variables are
20*4d7e907cSAndroid Build Coastguard Workeraccesed from the legacy hal event loop thread as well.
21*4d7e907cSAndroid Build Coastguard Worker
22*4d7e907cSAndroid Build Coastguard WorkerSynchronization Solution
23*4d7e907cSAndroid Build Coastguard Worker========================
24*4d7e907cSAndroid Build Coastguard WorkerAdding a global lock seems to be the most trivial solution to the problem.
25*4d7e907cSAndroid Build Coastguard Workera) All of the asynchronous "C" style callbacks will acquire the global lock
26*4d7e907cSAndroid Build Coastguard Workerbefore invoking the corresponding "std::function" callback variables.
27*4d7e907cSAndroid Build Coastguard Workerb) All of the AIDL methods will also acquire the global lock before processing
28*4d7e907cSAndroid Build Coastguard Worker(in aidl_return_util::validateAndCall()).
29*4d7e907cSAndroid Build Coastguard Worker
30*4d7e907cSAndroid Build Coastguard WorkerNote: It's important that we only acquire the global lock for asynchronous
31*4d7e907cSAndroid Build Coastguard Workercallbacks, because there is no guarantee (or documentation to clarify) that the
32*4d7e907cSAndroid Build Coastguard Workersynchronous callbacks are invoked on the same invocation thread. If that is not
33*4d7e907cSAndroid Build Coastguard Workerthe case in some implementation, we will end up deadlocking the system since the
34*4d7e907cSAndroid Build Coastguard WorkerAIDL thread would have acquired the global lock which is needed by the
35*4d7e907cSAndroid Build Coastguard Workersynchronous callback executed on the legacy hal event loop thread.
36