Fix hang caused by recursive mutex.
Fix disconnect caused by getPosition() failing, which was
just because the stream wasn't ready yet.
Bug:
63775537
Bug:
63709749
Test: run "aaudio_loopback -pl -Pl -c2 -n6 -te -m" many times
Change-Id: Ic1d54360b55cfc8ecc1809584c262bc0976c58bb
case AAUDIO_ERROR_NULL:
status = UNEXPECTED_NULL;
break;
+ case AAUDIO_ERROR_UNAVAILABLE:
+ status = NOT_ENOUGH_DATA;
+ break;
+
// TODO translate these result codes
case AAUDIO_ERROR_INTERNAL:
case AAUDIO_ERROR_UNIMPLEMENTED:
- case AAUDIO_ERROR_UNAVAILABLE:
case AAUDIO_ERROR_NO_FREE_HANDLES:
case AAUDIO_ERROR_NO_MEMORY:
case AAUDIO_ERROR_TIMEOUT:
case WOULD_BLOCK:
result = AAUDIO_ERROR_WOULD_BLOCK;
break;
+ case NOT_ENOUGH_DATA:
+ result = AAUDIO_ERROR_UNAVAILABLE;
+ break;
default:
result = AAUDIO_ERROR_INTERNAL;
break;
}
aaudio_result_t AAudioServiceEndpoint::startStream(sp<AAudioServiceStreamShared> sharedStream) {
- // TODO use real-time technique to avoid mutex, eg. atomic command FIFO
aaudio_result_t result = AAUDIO_OK;
- std::lock_guard<std::mutex> lock(mLockStreams);
if (++mRunningStreams == 1) {
+ // TODO use real-time technique to avoid mutex, eg. atomic command FIFO
+ std::lock_guard<std::mutex> lock(mLockStreams);
result = getStreamInternal()->requestStart();
startSharingThread_l();
}
}
aaudio_result_t AAudioServiceEndpoint::stopStream(sp<AAudioServiceStreamShared> sharedStream) {
- int numRunningStreams = 0;
- {
- std::lock_guard<std::mutex> lock(mLockStreams);
- numRunningStreams = --mRunningStreams;
- }
- if (numRunningStreams == 0) {
- // Don't call this under a lock because the callbackLoop also uses the lock.
+ // Don't lock here because the disconnectRegisteredStreams also uses the lock.
+ if (--mRunningStreams == 0) { // atomic
stopSharingThread();
getStreamInternal()->requestStop();
}
virtual AudioStreamInternal *getStreamInternal() = 0;
- std::atomic<bool> mCallbackEnabled;
+ std::atomic<bool> mCallbackEnabled{false};
mutable std::mutex mLockStreams;
std::vector<android::sp<AAudioServiceStreamShared>> mRegisteredStreams;
- size_t mRunningStreams = 0;
+ std::atomic<int> mRunningStreams{0};
private:
aaudio_result_t startSharingThread_l();
// (long long) command.timestamp.timestamp);
command.what = AAudioServiceMessage::code::TIMESTAMP;
result = writeUpMessageQueue(&command);
+ } else if (result == AAUDIO_ERROR_UNAVAILABLE) {
+ result = AAUDIO_OK; // just not available yet, try again later
}
return result;
}
aaudio_result_t sendCurrentTimestamp();
+ /**
+ * @param positionFrames
+ * @param timeNanos
+ * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error
+ */
virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
virtual aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) = 0;
return AAUDIO_ERROR_NULL;
}
status_t status = mMmapStream->getMmapPosition(&position);
- if (status != OK) {
- ALOGE("sendCurrentTimestamp(): getMmapPosition() returned %d", status);
+ aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
+ if (result == AAUDIO_ERROR_UNAVAILABLE) {
+ ALOGW("sendCurrentTimestamp(): getMmapPosition() has no position data yet");
+ } else if (result != AAUDIO_OK) {
+ ALOGE("sendCurrentTimestamp(): getMmapPosition() returned status %d", status);
disconnect();
- return AAudioConvert_androidToAAudioResult(status);
} else {
mFramesRead.update32(position.position_frames);
*positionFrames = mFramesRead.get();
*timeNanos = position.time_nanoseconds;
}
- return AAUDIO_OK;
+ return result;
}
void AAudioServiceStreamMMAP::onTearDown() {