1dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk/* 2dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * Copyright (C) 2016 The Android Open Source Project 3dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * 4dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * you may not use this file except in compliance with the License. 6dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * You may obtain a copy of the License at 7dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * 8dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 9dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * 10dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * Unless required by applicable law or agreed to in writing, software 11dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * See the License for the specific language governing permissions and 14dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk * limitations under the License. 15dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk */ 16dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#define LOG_TAG "AAudioService" 18dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk//#define LOG_NDEBUG 0 19dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk#include <utils/Log.h> 20dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 21dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk#include <pthread.h> 22dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 23a4eb0d86a29be2763be5fac51727858d5095794bPhil Burk#include <aaudio/AAudio.h> 24c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utility/AAudioUtilities.h> 25dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 265ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "AAudioThread.h" 27dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 285ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio; 29dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 30dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 31c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil BurkAAudioThread::AAudioThread() 32c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk : mRunnable(nullptr) 33c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk , mHasThread(false) { 34c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // mThread is a pthread_t of unknown size so we need memset(). 35dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk memset(&mThread, 0, sizeof(mThread)); 36dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk} 37dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkvoid AAudioThread::dispatch() { 39dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk if (mRunnable != nullptr) { 40dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk mRunnable->run(); 41dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk } else { 42dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk run(); 43dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk } 44dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk} 45dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 46dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk// This is the entry point for the new thread created by createThread(). 47dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk// It converts the 'C' function call to a C++ method call. 485ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkstatic void * AAudioThread_internalThreadProc(void *arg) { 495ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk AAudioThread *aaudioThread = (AAudioThread *) arg; 505ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudioThread->dispatch(); 51dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk return nullptr; 52dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk} 53dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 545ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AAudioThread::start(Runnable *runnable) { 55dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk if (mHasThread) { 56c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("AAudioThread::start() - mHasThread.load() already true"); 575ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 58dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk } 59c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // mRunnable will be read by the new thread when it starts. 60c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // pthread_create() forces a memory synchronization so mRunnable does not need to be atomic. 61c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mRunnable = runnable; 625ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk int err = pthread_create(&mThread, nullptr, AAudioThread_internalThreadProc, this); 63dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk if (err != 0) { 64c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("AAudioThread::start() - pthread_create() returned %d %s", err, strerror(err)); 65c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAudioConvert_androidToAAudioResult(-err); 66dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk } else { 67dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk mHasThread = true; 685ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 69dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk } 70dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk} 71dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 725ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AAudioThread::stop() { 73dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk if (!mHasThread) { 745ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 75dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk } 76dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk int err = pthread_join(mThread, nullptr); 77dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk mHasThread = false; 78c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (err != 0) { 79c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("AAudioThread::stop() - pthread_join() returned %d %s", err, strerror(err)); 80c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAudioConvert_androidToAAudioResult(-err); 81c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } else { 82c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_OK; 83c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 84dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk} 85dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk 86