Fix races when content providers are acquired and released.
This change fixes race conditions that occur very regularly when content providers are accessed from multiple threads at the same time. When a content provider is not already in the application's cache, the application needs to ask the ActivityManager to obtain it. Meanwhile, another thread can come along and do the same thing. This can cause problems because the application attempts to install two copies of the provider and the reference counts and other bookkeeping can get muddled. Similarly, there are races between releasing the last reference to a content provider and acquiring the content provider. It's possible for one thread to snatch the content provider from the jaws of death. We need to handle this explicitly to ensure that the content provider does not accidentally get released right after it was acquired by the other thread. This change ensures that the reference count bookkeeping and provider map are maintained in parallel while holding the same lock. Previously because the lock was dropped and reacquired in the middle of acquisition and removal, it was possible for a content provider with a zero reference count to be returned to the application. Likewise, it was possible for a content provider with a non-zero reference count to be disposed! This change also performs compensatory actions when races are detected to ensure that the necessary invariants are maintained throughout. In particular, it ensures that the application drops a duplicate reference to a content provider when no longer needed. Another way to solve this problem would be to explicitly prevent the races from happening in the first place by maintaining a table of content providers that are in the process of being acquired. The first thread to attempt to acquire the provider would store a record. The next thread would find the record and block until the first thread was finished. I chose not to implement the code in that manner because we would still have needed to perform compensatory actions in the case where the same provider binder has multiple logical names. Also, it could cause deadlocks if the attempt to acquire a content provider were re-entrant for some bizarre reason. Bug: 5547357 Change-Id: I2ad39a8acc30aaf7ae5354decd0a0a41e9b9c3da
Loading
Please register or sign in to comment