diff options
author | Glenn Kasten <gkasten@google.com> | 2014-01-13 10:21:48 -0800 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2014-01-24 13:19:59 -0800 |
commit | 38e905b3cbba4da443d799b16999989781afc6d8 (patch) | |
tree | 47b872b97f1af95c3e0ceefb1f8d56c9ae7a67fc /media/libmedia/AudioRecord.cpp | |
parent | f0002d142e6d24c5438600b2c259679de710f8ac (diff) | |
download | frameworks_av-38e905b3cbba4da443d799b16999989781afc6d8.zip frameworks_av-38e905b3cbba4da443d799b16999989781afc6d8.tar.gz frameworks_av-38e905b3cbba4da443d799b16999989781afc6d8.tar.bz2 |
Refactor code related to I/O handles to reduce chance for leaks
The AudioRecord input handle code was refactored earlier
to fix a potential handle leak, and to simplify the code:
> Change-Id: I124dce344b1d11c2dd66ca5e2c9aec0c52c230e2
This changelist refactors AudioTrack similarly,
and adds further cleanup of both AudioTrack and AudioRecord.
We attempt to implement the rules for referencing counting I/O handles,
but there is still the possibility of a handle leak if the client process
dies after allocating the handle reference but before releasing it.
That issue is being tracked separately.
Details:
- AudioSystem::getOutput() is now called within createTrack_l
- restoreTrack_l was missing offload info
now it has the info available,
but is not yet being called for offloaded tracks
- AudioTrack::getOutput() is now const
- Remove getOutput_l()
Change-Id: I44a0a623d24fc5847bcac0939c276400568adbca
Diffstat (limited to 'media/libmedia/AudioRecord.cpp')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 0673079..a999e7e 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -244,7 +244,7 @@ status_t AudioRecord::set( // create the IAudioRecord status = openRecord_l(0 /*epoch*/); - if (status) { + if (status != NO_ERROR) { return status; } @@ -463,6 +463,9 @@ status_t AudioRecord::openRecord_l(size_t epoch) ALOGE("Could not get audio input for record source %d", mInputSource); return BAD_VALUE; } + { + // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger, + // we must release it ourselves if anything goes wrong. size_t temp = mFrameCount; // temp may be replaced by a revised value of frameCount, // but we will still need the original value also @@ -480,9 +483,11 @@ status_t AudioRecord::openRecord_l(size_t epoch) if (record == 0 || status != NO_ERROR) { ALOGE("AudioFlinger could not create record track, status: %d", status); - AudioSystem::releaseInput(input); - return status; + goto release; } + // AudioFlinger now owns the reference to the I/O handle, + // so we are no longer responsible for releasing it. + sp<IMemory> iMem = record->getCblk(); if (iMem == 0) { ALOGE("Could not get control block"); @@ -497,6 +502,8 @@ status_t AudioRecord::openRecord_l(size_t epoch) mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); mDeathNotifier.clear(); } + + // We retain a copy of the I/O handle, but don't own the reference mInput = input; mAudioRecord = record; mCblkMemory = iMem; @@ -540,6 +547,14 @@ status_t AudioRecord::openRecord_l(size_t epoch) mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this); return NO_ERROR; + } + +release: + AudioSystem::releaseInput(input); + if (status == NO_ERROR) { + status = NO_INIT; + } + return status; } status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) |