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