CEngine.c revision b0a0555e2fcad41d3ee0c45f0f75ed556dbee282
1437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten/* 2437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 3437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * 4437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * you may not use this file except in compliance with the License. 6437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * You may obtain a copy of the License at 7437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * 8437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * 10437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * Unless required by applicable law or agreed to in writing, software 11437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * See the License for the specific language governing permissions and 14437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten * limitations under the License. 15437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten */ 16437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten 1710ee2bc6119445f4339ecef998c40c9cc95057cdGlenn Kasten/** \file CEngine.c Engine class */ 18437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten 19437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten#include "sles_allinclusive.h" 20437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten 21437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten 2210ee2bc6119445f4339ecef998c40c9cc95057cdGlenn Kasten/** \brief Hook called by Object::Realize when an engine is realized */ 23158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 24437f9ab9914ea61112aa496a047162a0d22194cdGlenn KastenSLresult CEngine_Realize(void *self, SLboolean async) 25437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten{ 26437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten CEngine *this = (CEngine *) self; 27bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten int err = pthread_create(&this->mSyncThread, (const pthread_attr_t *) NULL, sync_start, this); 28bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten SLresult result = err_to_result(err); 29437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten if (SL_RESULT_SUCCESS != result) 30437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten return result; 31437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten result = ThreadPool_init(&this->mEngine.mThreadPool, 0, 0); 32437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten if (SL_RESULT_SUCCESS != result) { 33437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten this->mEngine.mShutdown = SL_BOOLEAN_TRUE; 34437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten (void) pthread_join(this->mSyncThread, (void **) NULL); 35437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten return result; 36437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten } 37437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten#ifdef USE_SDL 38bc1596c33e134859d3ae3182d641b2dd03405b5dGlenn Kasten SDL_open(&this->mEngine); 39437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten#endif 40437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten return SL_RESULT_SUCCESS; 41437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten} 42437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten 43158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 4410ee2bc6119445f4339ecef998c40c9cc95057cdGlenn Kasten/** \brief Hook called by Object::Destroy when an engine is destroyed */ 45158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 46437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenvoid CEngine_Destroy(void *self) 47437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten{ 48437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten CEngine *this = (CEngine *) self; 49b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten 50b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten // Verify that there are no extant objects 51b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten unsigned instanceCount = this->mEngine.mInstanceCount; 52b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten unsigned instanceMask = this->mEngine.mInstanceMask; 53b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten if ((0 < instanceCount) || (0 != instanceMask)) { 54b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten SL_LOGE("Object::Destroy of engine %p with %u active objects", this, instanceCount); 55b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten while (0 != instanceMask) { 56b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten unsigned i = ctz(instanceMask); 57b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten assert(MAX_INSTANCE > i); 58b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten SL_LOGE("Object::Destroy of engine %p with active object ID %u", this, i + 1); 59b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten instanceMask &= ~(1 << i); 60b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten } 61b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten 62b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten } 63b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten 64b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten // Announce to the sync thread that engine is shutting down; it polls so should see it soon 65437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten this->mEngine.mShutdown = SL_BOOLEAN_TRUE; 66b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten // Wait for the sync thread to acknowledge the shutdown 67b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten while (!this->mEngine.mShutdownAck) { 68b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten object_cond_wait(&this->mObject); 69b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten } 70b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten // The sync thread should have exited by now, so collect it by joining 71b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten (void) pthread_join(this->mSyncThread, (void **) NULL); 72b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten 73b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten // Shutdown the thread pool used for asynchronous operations (there should not be any) 74b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten ThreadPool_deinit(&this->mEngine.mThreadPool); 75b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten 76ff9f51f17b6c00beaa51698e22873a979c7b3ff6Glenn Kasten#if defined(ANDROID) && !defined(USE_BACKPORT) 771f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi // free effect data 781f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi // free EQ data 791f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi if ((0 < this->mEngine.mEqNumPresets) && (NULL != this->mEngine.mEqPresetNames)) { 801f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi for(uint32_t i = 0 ; i < this->mEngine.mEqNumPresets ; i++) { 811f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi if (NULL != this->mEngine.mEqPresetNames[i]) { 821f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi delete [] this->mEngine.mEqPresetNames[i]; 831f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi } 841f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi } 851f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi delete [] this->mEngine.mEqPresetNames; 861f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi } 871f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi#endif 88b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten 89b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten#ifdef USE_SDL 90b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten SDL_close(); 91b0a0555e2fcad41d3ee0c45f0f75ed556dbee282Glenn Kasten#endif 921f5702ed2239c79b701aa8cc3c675798b34a9656Jean-Michel Trivi 93437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten} 94