1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** \file CEngine.c Engine class */ 18 19#include "sles_allinclusive.h" 20 21 22/** \brief Hook called by Object::Realize when an engine is realized */ 23 24SLresult CEngine_Realize(void *self, SLboolean async) 25{ 26 CEngine *this = (CEngine *) self; 27 SLresult result; 28#ifndef ANDROID 29 // create the sync thread 30 int err = pthread_create(&this->mSyncThread, (const pthread_attr_t *) NULL, sync_start, this); 31 result = err_to_result(err); 32 if (SL_RESULT_SUCCESS != result) 33 return result; 34#endif 35 // initialize the thread pool for asynchronous operations 36 result = ThreadPool_init(&this->mEngine.mThreadPool, 0, 0); 37 if (SL_RESULT_SUCCESS != result) { 38 this->mEngine.mShutdown = SL_BOOLEAN_TRUE; 39 (void) pthread_join(this->mSyncThread, (void **) NULL); 40 return result; 41 } 42#ifdef USE_SDL 43 SDL_open(&this->mEngine); 44#endif 45 return SL_RESULT_SUCCESS; 46} 47 48 49/** \brief Hook called by Object::Resume when an engine is resumed */ 50 51SLresult CEngine_Resume(void *self, SLboolean async) 52{ 53 return SL_RESULT_SUCCESS; 54} 55 56 57/** \brief Hook called by Object::Destroy when an engine is destroyed */ 58 59void CEngine_Destroy(void *self) 60{ 61 CEngine *this = (CEngine *) self; 62 63 // Verify that there are no extant objects 64 unsigned instanceCount = this->mEngine.mInstanceCount; 65 unsigned instanceMask = this->mEngine.mInstanceMask; 66 if ((0 < instanceCount) || (0 != instanceMask)) { 67 SL_LOGE("Object::Destroy(%p) for engine ignored; %u total active objects", 68 this, instanceCount); 69 while (0 != instanceMask) { 70 unsigned i = ctz(instanceMask); 71 assert(MAX_INSTANCE > i); 72 SL_LOGE("Object::Destroy(%p) for engine ignored; active object ID %u at %p", 73 this, i + 1, this->mEngine.mInstances[i]); 74 instanceMask &= ~(1 << i); 75 } 76 } 77 78 // If engine was created but not realized, there will be no sync thread yet 79 pthread_t zero; 80 memset(&zero, 0, sizeof(pthread_t)); 81 if (0 != memcmp(&zero, &this->mSyncThread, sizeof(pthread_t))) { 82 83 // Announce to the sync thread that engine is shutting down; it polls so should see it soon 84 this->mEngine.mShutdown = SL_BOOLEAN_TRUE; 85 // Wait for the sync thread to acknowledge the shutdown 86 while (!this->mEngine.mShutdownAck) { 87 object_cond_wait(&this->mObject); 88 } 89 // The sync thread should have exited by now, so collect it by joining 90 (void) pthread_join(this->mSyncThread, (void **) NULL); 91 92 } 93 94 // Shutdown the thread pool used for asynchronous operations (there should not be any) 95 ThreadPool_deinit(&this->mEngine.mThreadPool); 96 97#ifdef USE_SDL 98 SDL_close(); 99#endif 100 101} 102 103 104/** \brief Hook called by Object::Destroy before an engine is about to be destroyed */ 105 106bool CEngine_PreDestroy(void *self) 107{ 108 return true; 109} 110