diff options
| author | 2013-06-18 17:25:37 -0700 | |
|---|---|---|
| committer | 2013-07-24 16:18:12 -0700 | |
| commit | a7b0f04aaf7f04a9617dbbc839b1aaa6f20ca6d6 (patch) | |
| tree | 67cd9f59089c11be44da689db66771f6ff0d0baa | |
| parent | 1d4f79c48237e8720538b59cd2ecb5a2a5e5e9d8 (diff) | |
defaultServiceManager wait for service manager ready
If the service manager is not ready when we attempt to create a local
proxy, fail and retry.
Change-Id: I7d7300bc07cd70608793479aa3da282d066da7f6
| -rw-r--r-- | libs/binder/IServiceManager.cpp | 4 | ||||
| -rw-r--r-- | libs/binder/ProcessState.cpp | 27 |
2 files changed, 30 insertions, 1 deletions
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 1750640fc1..a341ca8ed5 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -37,9 +37,11 @@ sp<IServiceManager> defaultServiceManager() { AutoMutex _l(gDefaultServiceManagerLock); - if (gDefaultServiceManager == NULL) { + while (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); + if (gDefaultServiceManager == NULL) + sleep(1); } } diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 294e1d4898..c1e49bc8f6 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -194,6 +194,33 @@ sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { + if (handle == 0) { + // Special case for context manager... + // The context manager is the only object for which we create + // a BpBinder proxy without already holding a reference. + // Perform a dummy transaction to ensure the context manager + // is registered before we create the first local reference + // to it (which will occur when creating the BpBinder). + // If a local reference is created for the BpBinder when the + // context manager is not present, the driver will fail to + // provide a reference to the context manager, but the + // driver API does not return status. + // + // Note that this is not race-free if the context manager + // dies while this code runs. + // + // TODO: add a driver API to wait for context manager, or + // stop special casing handle 0 for context manager and add + // a driver API to get a handle to the context manager with + // proper reference counting. + + Parcel data; + status_t status = IPCThreadState::self()->transact( + 0, IBinder::PING_TRANSACTION, data, NULL, 0); + if (status == DEAD_OBJECT) + return NULL; + } + b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); |