android / ndk

The Android Native Development Kit
2k stars 257 forks source link

[question] Robust mutex support #1181

Open sdaly2107 opened 4 years ago

sdaly2107 commented 4 years ago

We have developed a cross platform foundation layer- one of the objects in there is a NamedMutex. Windows named mutex are robust by default and on Linux we set the following robust attribute -

pthread_mutexattr_setrobust(&mutexAttr, PTHREAD_MUTEX_ROBUST)

On Android we compile this out, but it means we cannot recover from an abandoned mutex on Android. Is there any planned support for this?

On another note, this requires shared memory, but we require the same block of memory for a given key. We have this working using some 3rd party library and some modifications. Is there any planned support for this natively? We understand the recommended approach is to share the fd via a binder service - at this point though we are purely developing an SDK at the native level.

enh-google commented 4 years ago

no, no current plans to implement robust mutexes.

there is an NDK binder API available from 29 on.

sdaly2107 commented 4 years ago

Thanks for the clarification.

So does that mean we should be able to use ASharedMemory_create and share the FD via a native binder to get access to the same block?

enh-google commented 4 years ago

Thanks for the clarification.

while i'm here, let me give a more detailed brain dump. this probably isn't useful to many, but you might be the rare exception...

historically i believed that we couldn't retrofit robust mutexes to Android's mutexes without an ABI break. which wasn't going to happen, (a) because we don't do that, and (b) because the functionality is so niche that it wouldn't even make sense to try to think of workarounds, and (c) because we wouldn't want to pay the cost of the size increase.

i think now that we could implement this, because the extra list you need to maintain lives in the thread rather than the mutex. so we might implement this at some point, but not any time soon because it's still very niche.

but if your "cross platform foundation layer" has its own thread wrapper as well as the NamedMutex, you can implement this functionality yourself there. one day -- assuming this does eventually get implemented in the system -- we'll tread on each others' toes. but until then this would give you something you could use, including on existing devices that already shipped.

So does that mean we should be able to use ASharedMemory_create and share the FD via a native binder to get access to the same block?

i believe that's one of the intended uses, yes.

sdaly2107 commented 4 years ago

OK, so we could extend the block of shared mem used by the mutex to include owning tid - then in our thread wrapper update this on thread exit. When locking, owners could be checked to see if they are dead. Won't work if clients use std::thread or std::async though. Hopefully it makes its way in one day :)

Will give this a shot, thanks for the info!

jmgao commented 4 years ago

I don't think you even need a wrapper for thread: you just need thread local storage that gives you a callback when the thread exits, which pthread_key_create does for you.

sdaly2107 commented 4 years ago

I don't think you even need a wrapper for thread: you just need thread local storage that gives you a callback when the thread exits, which pthread_key_create does for you.

On a side note, we came across issues with segfaults on process termination when using thread_local variables and loading/unloading shared objects multiple times using dlopen/dlcose (I know the advice is to not use dlcose, which may be the route eventually taken). For now we refactored to avoid thread_local and everything is working well. I wonder if the same issues would be seen using pthread_key_create and pthread_setspecific as we observed with thread_local and __thread.

alexcohn commented 4 years ago

Note that you can use unix domain sockets to pass fd across processes.