Wait for buffers to drain
When a BufferQueue producer disconnects and reconnects, we retain the previously-queued buffers but empty the slots. This allows the number of queued buffers to grow without limit. The low-memory killer does not approve. Bug 11069934 Change-Id: Ia2eaa954c7a3904b54209a3701dba01689e204d8
This commit is contained in:
parent
dacd415963
commit
8507586903
@ -644,6 +644,7 @@ status_t BufferQueue::connect(const sp<IBinder>& token,
|
||||
producerControlledByApp ? "true" : "false");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
retry:
|
||||
if (mAbandoned) {
|
||||
ST_LOGE("connect: BufferQueue has been abandoned!");
|
||||
return NO_INIT;
|
||||
@ -654,17 +655,30 @@ status_t BufferQueue::connect(const sp<IBinder>& token,
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
if (mConnectedApi != NO_CONNECTED_API) {
|
||||
ST_LOGE("connect: already connected (cur=%d, req=%d)",
|
||||
mConnectedApi, api);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// If we disconnect and reconnect quickly, we can be in a state where our slots are
|
||||
// empty but we have many buffers in the queue. This can cause us to run out of
|
||||
// memory if we outrun the consumer. Wait here if it looks like we have too many
|
||||
// buffers queued up.
|
||||
int maxBufferCount = getMaxBufferCountLocked(false); // worst-case, i.e. largest value
|
||||
if (mQueue.size() > (size_t) maxBufferCount) {
|
||||
// TODO: make this bound tighter?
|
||||
ST_LOGV("queue size is %d, waiting", mQueue.size());
|
||||
mDequeueCondition.wait(mMutex);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
int err = NO_ERROR;
|
||||
switch (api) {
|
||||
case NATIVE_WINDOW_API_EGL:
|
||||
case NATIVE_WINDOW_API_CPU:
|
||||
case NATIVE_WINDOW_API_MEDIA:
|
||||
case NATIVE_WINDOW_API_CAMERA:
|
||||
if (mConnectedApi != NO_CONNECTED_API) {
|
||||
ST_LOGE("connect: already connected (cur=%d, req=%d)",
|
||||
mConnectedApi, api);
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
mConnectedApi = api;
|
||||
output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size());
|
||||
|
||||
@ -678,7 +692,6 @@ status_t BufferQueue::connect(const sp<IBinder>& token,
|
||||
ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user