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