Skip to content

Commit 535f8f9

Browse files
author
Steven Moreland
committed
sm: repoll after handling client callbacks
There is a bug in the binder driver where polling clients can sometimes freeze, and this is the workaround, though it hasn't yet been confirmed this issue happens in servicemanager. Bug: 316829336 Test: boot Change-Id: I2867a2d1468e92ddc51967c4cf05e528d38d00fd
1 parent a8d0a4e commit 535f8f9

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

cmds/servicemanager/main.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,12 @@ class BinderCallback : public LooperCallback {
4040
public:
4141
static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
4242
sp<BinderCallback> cb = sp<BinderCallback>::make();
43+
cb->mLooper = looper;
4344

44-
int binder_fd = -1;
45-
IPCThreadState::self()->setupPolling(&binder_fd);
46-
LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
45+
IPCThreadState::self()->setupPolling(&cb->mBinderFd);
46+
LOG_ALWAYS_FATAL_IF(cb->mBinderFd < 0, "Failed to setupPolling: %d", cb->mBinderFd);
4747

48-
int ret = looper->addFd(binder_fd,
49-
Looper::POLL_CALLBACK,
50-
Looper::EVENT_INPUT,
51-
cb,
48+
int ret = looper->addFd(cb->mBinderFd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
5249
nullptr /*data*/);
5350
LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
5451

@@ -59,13 +56,26 @@ class BinderCallback : public LooperCallback {
5956
IPCThreadState::self()->handlePolledCommands();
6057
return 1; // Continue receiving callbacks.
6158
}
59+
60+
void repoll() {
61+
if (!mLooper->repoll(mBinderFd)) {
62+
ALOGE("Failed to repoll binder FD.");
63+
}
64+
}
65+
66+
private:
67+
sp<Looper> mLooper;
68+
int mBinderFd = -1;
6269
};
6370

6471
// LooperCallback for IClientCallback
6572
class ClientCallbackCallback : public LooperCallback {
6673
public:
67-
static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
74+
static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper,
75+
const sp<ServiceManager>& manager,
76+
sp<BinderCallback> binderCallback) {
6877
sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager);
78+
cb->mBinderCallback = binderCallback;
6979

7080
int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/);
7181
LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno);
@@ -102,12 +112,15 @@ class ClientCallbackCallback : public LooperCallback {
102112
}
103113

104114
mManager->handleClientCallbacks();
115+
mBinderCallback->repoll(); // b/316829336
116+
105117
return 1; // Continue receiving callbacks.
106118
}
107119
private:
108120
friend sp<ClientCallbackCallback>;
109121
ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {}
110122
sp<ServiceManager> mManager;
123+
sp<BinderCallback> mBinderCallback;
111124
};
112125

113126
int main(int argc, char** argv) {
@@ -139,8 +152,8 @@ int main(int argc, char** argv) {
139152

140153
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
141154

142-
BinderCallback::setupTo(looper);
143-
ClientCallbackCallback::setupTo(looper, manager);
155+
sp<BinderCallback> binderCallback = BinderCallback::setupTo(looper);
156+
ClientCallbackCallback::setupTo(looper, manager, binderCallback);
144157

145158
#ifndef VENDORSERVICEMANAGER
146159
if (!SetProperty("servicemanager.ready", "true")) {

0 commit comments

Comments
 (0)