IObject.c revision 1d081e49a10543018e1ae33792bd3d30504719ba
10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2010 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* Object implementation */ 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 19a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "sles_allinclusive.h" 20b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt 21a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// Called by a worker thread to handle an asynchronous Object.Realize. 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// Parameter self is the Object. 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic void HandleRealize(void *self, int unused) 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 270c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville 28ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // validate input parameters 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(NULL != this); 31a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const ClassTable *class__ = this->mClass; 32b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt assert(NULL != class__); 33203e588e3c42a81aa8a56f595119c181a63b12caWink Saville AsyncHook realize = class__->mRealize; 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLresult result; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLuint8 state; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // check object state 385fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville object_lock_exclusive(this); 39ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville state = this->mState; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (state) { 41454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville 42d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka case SL_OBJECT_STATE_REALIZING_1: // normal case 43d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka if (NULL != realize) { 44d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka this->mState = SL_OBJECT_STATE_REALIZING_2; 45e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka object_unlock_exclusive(this); 46e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka // Note that the mutex is unlocked during the realize hook 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = (*realize)(this, SL_BOOLEAN_TRUE); 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(SL_OBJECT_STATE_REALIZING_2 == this->mState); 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_RESULT_SUCCESS == result ? SL_OBJECT_STATE_REALIZED : 515fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville SL_OBJECT_STATE_UNREALIZED; 525fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville } else { 535fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville result = SL_RESULT_SUCCESS; 5460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey state = SL_OBJECT_STATE_REALIZED; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville break; 57e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka 58e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case SL_OBJECT_STATE_REALIZING_1A: // operation was aborted while on work queue 59e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka result = SL_RESULT_OPERATION_ABORTED; 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_UNREALIZED; 61ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville break; 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 63f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville default: // impossible 64f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville assert(SL_BOOLEAN_FALSE); 6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville result = SL_RESULT_INTERNAL_ERROR; 6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville break; 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 680c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville } 690c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville 705fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville // mutex is locked, update state 71ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville this->mState = state; 72ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville 73ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // Make a copy of these, so we can call the callback with mutex unlocked 74ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville slObjectCallback callback = this->mCallback; 75ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville void *context = this->mContext; 76ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville object_unlock_exclusive(this); 77ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville 78ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // Note that the mutex is unlocked during the callback 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL != callback) { 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (*callback)(&this->mItf, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, NULL); 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic SLresult IObject_Realize(SLObjectItf self, SLboolean async) 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLuint8 state; 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const ClassTable *class__ = this->mClass; 9222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville bool isSharedEngine = false; 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // note that SL_OBJECTID_ENGINE and XA_OBJECTID_ENGINE map to same class 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (class__ == objectIDtoClass(SL_OBJECTID_ENGINE)) { 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // important: the lock order is engine followed by theOneTrueMutex 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int ok = pthread_mutex_lock(&theOneTrueMutex); 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(0 == ok); 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville isSharedEngine = 1 < theOneTrueRefCount; 10022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville ok = pthread_mutex_unlock(&theOneTrueMutex); 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(0 == ok); 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = this->mState; 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Reject redundant calls to Realize, except on a shared engine 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SL_OBJECT_STATE_UNREALIZED != state) { 106203e588e3c42a81aa8a56f595119c181a63b12caWink Saville object_unlock_exclusive(this); 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // redundant realize on the shared engine is permitted 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isSharedEngine && (SL_OBJECT_STATE_REALIZED == state)) { 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_PRECONDITIONS_VIOLATED; 112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Asynchronous: mark operation pending and cancellable 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (async && (SL_OBJECTID_ENGINE != class__->mSLObjectID)) { 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_REALIZING_1; 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Synchronous: mark operation pending and non-cancellable 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_REALIZING_2; 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mState = state; 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (state) { 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZING_1: // asynchronous on non-Engine 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(async); 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = ThreadPool_add(&this->mEngine->mThreadPool, HandleRealize, this, 0); 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SL_RESULT_SUCCESS != result) { 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Engine was destroyed during realize, or insufficient memory 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mState = SL_OBJECT_STATE_UNREALIZED; 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZING_2: // synchronous, or asynchronous on Engine 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville { 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncHook realize = class__->mRealize; 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note that the mutex is unlocked during the realize hook 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = (NULL != realize) ? (*realize)(this, async) : SL_RESULT_SUCCESS; 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(SL_OBJECT_STATE_REALIZING_2 == this->mState); 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = (SL_RESULT_SUCCESS == result) ? SL_OBJECT_STATE_REALIZED : 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_OBJECT_STATE_UNREALIZED; 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mState = state; 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville slObjectCallback callback = this->mCallback; 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void *context = this->mContext; 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // asynchronous Realize on an Engine is actually done synchronously, but still has 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // callback because there is no thread pool yet to do it asynchronously. 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (async && (NULL != callback)) { 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (*callback)(&this->mItf, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville NULL); 152ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville } 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: // impossible 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(SL_BOOLEAN_FALSE); 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE 162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 1635fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 1645fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// Called by a worker thread to handle an asynchronous Object.Resume. 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// Parameter self is the Object. 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic void HandleResume(void *self, int unused) 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // valid input parameters 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(NULL != this); 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const ClassTable *class__ = this->mClass; 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(NULL != class__); 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncHook resume = class__->mResume; 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLresult result; 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLuint8 state; 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // check object state 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = this->mState; 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (state) { 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_1: // normal case 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL != resume) { 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mState = SL_OBJECT_STATE_RESUMING_2; 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note that the mutex is unlocked during the resume hook 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = (*resume)(this, SL_BOOLEAN_TRUE); 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(SL_OBJECT_STATE_RESUMING_2 == this->mState); 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_RESULT_SUCCESS == result ? SL_OBJECT_STATE_REALIZED : 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_OBJECT_STATE_SUSPENDED; 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_REALIZED; 1985fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville } 1995fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 2005fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 2015fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case SL_OBJECT_STATE_RESUMING_1A: // operation was aborted while on work queue 2025fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville result = SL_RESULT_OPERATION_ABORTED; 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_SUSPENDED; 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: // impossible 207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville assert(SL_BOOLEAN_FALSE); 208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville result = SL_RESULT_INTERNAL_ERROR; 209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville break; 210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 21303586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla // mutex is unlocked, update state 21403586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla this->mState = state; 215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 216049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville // Make a copy of these, so we can call the callback with mutex unlocked 217ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville slObjectCallback callback = this->mCallback; 218ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville void *context = this->mContext; 21922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville object_unlock_exclusive(this); 220f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville 221f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville // Note that the mutex is unlocked during the callback 222e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka if (NULL != callback) { 223e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka (*callback)(&this->mItf, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, NULL); 22422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } 2255fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville} 226c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro 227c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro 228c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshirostatic SLresult IObject_Resume(SLObjectItf self, SLboolean async) 229ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville{ 230ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville SL_ENTER_INTERFACE 23103586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla 23203586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla IObject *this = (IObject *) self; 23303586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla const ClassTable *class__ = this->mClass; 23403586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla SLuint8 state; 23503586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla object_lock_exclusive(this); 23603586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla state = this->mState; 23703586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla // Reject redundant calls to Resume 238ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville if (SL_OBJECT_STATE_SUSPENDED != state) { 23922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville object_unlock_exclusive(this); 240c26fb77c4e637466cf0483a4995fe82e6f68b8d3Alex Yakavenka result = SL_RESULT_PRECONDITIONS_VIOLATED; 2415fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville } else { 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Asynchronous: mark operation pending and cancellable 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (async) { 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_RESUMING_1; 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Synchronous: mark operatio pending and non-cancellable 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_RESUMING_2; 248ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville } 249ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville this->mState = state; 250ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville object_unlock_exclusive(this); 251ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville switch (state) { 252ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville case SL_OBJECT_STATE_RESUMING_1: // asynchronous 253ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville assert(async); 254ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville result = ThreadPool_add(&this->mEngine->mThreadPool, HandleResume, this, 0); 255ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville if (SL_RESULT_SUCCESS != result) { 256ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // Engine was destroyed during resume, or insufficient memory 257ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville object_lock_exclusive(this); 258ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville this->mState = SL_OBJECT_STATE_SUSPENDED; 259ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville object_unlock_exclusive(this); 260ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville } 261ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville break; 262ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville case SL_OBJECT_STATE_RESUMING_2: // synchronous 263ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville { 264ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville AsyncHook resume = class__->mResume; 265ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // Note that the mutex is unlocked during the resume hook 266203e588e3c42a81aa8a56f595119c181a63b12caWink Saville result = (NULL != resume) ? (*resume)(this, SL_BOOLEAN_FALSE) : SL_RESULT_SUCCESS; 267203e588e3c42a81aa8a56f595119c181a63b12caWink Saville object_lock_exclusive(this); 268203e588e3c42a81aa8a56f595119c181a63b12caWink Saville assert(SL_OBJECT_STATE_RESUMING_2 == this->mState); 269203e588e3c42a81aa8a56f595119c181a63b12caWink Saville this->mState = (SL_RESULT_SUCCESS == result) ? SL_OBJECT_STATE_REALIZED : 270203e588e3c42a81aa8a56f595119c181a63b12caWink Saville SL_OBJECT_STATE_SUSPENDED; 271203e588e3c42a81aa8a56f595119c181a63b12caWink Saville object_unlock_exclusive(this); 272203e588e3c42a81aa8a56f595119c181a63b12caWink Saville } 273203e588e3c42a81aa8a56f595119c181a63b12caWink Saville break; 274203e588e3c42a81aa8a56f595119c181a63b12caWink Saville default: // impossible 275203e588e3c42a81aa8a56f595119c181a63b12caWink Saville assert(SL_BOOLEAN_FALSE); 276203e588e3c42a81aa8a56f595119c181a63b12caWink Saville break; 277203e588e3c42a81aa8a56f595119c181a63b12caWink Saville } 278203e588e3c42a81aa8a56f595119c181a63b12caWink Saville } 279203e588e3c42a81aa8a56f595119c181a63b12caWink Saville 280f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville SL_LEAVE_INTERFACE 281f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville} 282f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville 283f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville 284f1317a4b3492218ac2e449ee990948bac0295b65Wink Savillestatic SLresult IObject_GetState(SLObjectItf self, SLuint32 *pState) 285f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville{ 286f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville SL_ENTER_INTERFACE 287f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville 288f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville if (NULL == pState) { 289f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville result = SL_RESULT_PARAMETER_INVALID; 290f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville } else { 291f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville IObject *this = (IObject *) self; 292f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville // Note that the state is immediately obsolete, so a peek lock is safe 293f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville object_lock_peek(this); 29403b37b67755a4033c6be32ae2e389c310e06e7d1Amit Mahajan SLuint8 state = this->mState; 29517a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa object_unlock_peek(this); 29617a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa // Re-map the realizing, resuming, and suspending states 29717a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa switch (state) { 29817a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa case SL_OBJECT_STATE_REALIZING_1: 29903b37b67755a4033c6be32ae2e389c310e06e7d1Amit Mahajan case SL_OBJECT_STATE_REALIZING_1A: 300f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville case SL_OBJECT_STATE_REALIZING_2: 301f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville case SL_OBJECT_STATE_DESTROYING: // application shouldn't call GetState after Destroy 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_UNREALIZED; 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_1: 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_1A: 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_2: 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_SUSPENDING: 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville state = SL_OBJECT_STATE_SUSPENDED; 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_UNREALIZED: 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZED: 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_SUSPENDED: 31322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville // These are the "official" object states, return them as is 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(SL_BOOLEAN_FALSE); 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *pState = state; 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic SLresult IObject_GetInterface(SLObjectItf self, const SLInterfaceID iid, void *pInterface) 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL == pInterface) { 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_PARAMETER_INVALID; 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void *interface = NULL; 33422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (NULL == iid) { 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_PARAMETER_INVALID; 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const ClassTable *class__ = this->mClass; 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int MPH, index; 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((0 > (MPH = IID_to_MPH(iid))) || 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // no need to check for an initialization hook 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (NULL == MPH_init_table[MPH].mInit) || 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (0 > (index = class__->mMPH_to_index[MPH]))) { 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_FEATURE_UNSUPPORTED; 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unsigned mask = 1 << index; 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((SL_OBJECT_STATE_REALIZED != this->mState) && 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville !(INTERFACE_PREREALIZE & class__->mInterfaces[index].mInterface)) { 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Can't get interface on an unrealized object unless pre-realize is ok 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_PRECONDITIONS_VIOLATED; 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if ((MPH_MUTESOLO == MPH) && (SL_OBJECTID_AUDIOPLAYER == 35322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville class__->mSLObjectID) && (1 == ((CAudioPlayer *) this)->mNumChannels)) { 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Can't get the MuteSolo interface of an audio player if the channel count is 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // mono, but _can_ get the MuteSolo interface if the channel count is unknown 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_FEATURE_UNSUPPORTED; 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (this->mInterfaceStates[index]) { 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_EXPOSED: 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_ADDED: 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville interface = (char *) this + class__->mInterfaces[index].mOffset; 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note that interface has been gotten, 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // for debugger and to detect incorrect use of interfaces 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!(this->mGottenMask & mask)) { 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mGottenMask |= mask; 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // This trickery validates the v-table 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ((size_t *) interface)[0] ^= ~0; 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Can't get interface if uninitialized, initialized, suspended, 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // suspending, resuming, adding, or removing 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_FEATURE_UNSUPPORTED; 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 38022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *(void **)pInterface = interface; 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 38622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic SLresult IObject_RegisterCallback(SLObjectItf self, 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville slObjectCallback callback, void *pContext) 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE 39222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mCallback = callback; 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mContext = pContext; 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 39922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** \brief This is internal common code for Abort and Destroy. 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: called with mutex unlocked, and returns with mutex locked. 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic void Abort_internal(IObject *this) 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const ClassTable *class__ = this->mClass; 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bool anyAsync = false; 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Abort asynchronous operations on the object 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (this->mState) { 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZING_1: // Realize 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mState = SL_OBJECT_STATE_REALIZING_1A; 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville anyAsync = true; 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_1: // Resume 421e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka this->mState = SL_OBJECT_STATE_RESUMING_1A; 422e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka anyAsync = true; 423e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka break; 424e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka case SL_OBJECT_STATE_REALIZING_1A: // Realize 4255fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case SL_OBJECT_STATE_REALIZING_2: 4265fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case SL_OBJECT_STATE_RESUMING_1A: // Resume 4275fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case SL_OBJECT_STATE_RESUMING_2: 4285fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville anyAsync = true; 4295fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4305fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case SL_OBJECT_STATE_DESTROYING: 4315fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville assert(false); 4325fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4335fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville default: 4345fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville } 4365fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 4375fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville // Abort asynchronous operations on interfaces 4385fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville SLuint8 *interfaceStateP = this->mInterfaceStates; 4395fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville unsigned index; 4400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville for (index = 0; index < class__->mInterfaceCount; ++index, ++interfaceStateP) { 4415fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville switch (*interfaceStateP) { 4425fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_ADDING_1: // AddInterface 4435fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville *interfaceStateP = INTERFACE_ADDING_1A; 4445fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville anyAsync = true; 4455fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4465fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_RESUMING_1: // ResumeInterface 4475fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville *interfaceStateP = INTERFACE_RESUMING_1A; 4485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville anyAsync = true; 4495fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4505fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_ADDING_1A: // AddInterface 4515fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_ADDING_2: 4525fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_RESUMING_1A: // ResumeInterface 4535fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_RESUMING_2: 4545fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville case INTERFACE_REMOVING: // not observable: RemoveInterface is synchronous & mutex locked 4555fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville anyAsync = true; 4565fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4570c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville default: 4585fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville break; 4595fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville } 4605fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville } 4615fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 4625fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville // Wait until all asynchronous operations either complete normally or recognize the abort 4635fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville while (anyAsync) { 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // FIXME should use condition variable instead of polling 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville usleep(20000); 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville anyAsync = false; 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (this->mState) { 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZING_1: // state 1 means it cycled during the usleep window 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_1: 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZING_1A: 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_REALIZING_2: 474e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka case SL_OBJECT_STATE_RESUMING_1A: 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_RESUMING_2: 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville anyAsync = true; 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SL_OBJECT_STATE_DESTROYING: 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(false); 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville default: 482b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal break; 483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville interfaceStateP = this->mInterfaceStates; 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (index = 0; index < class__->mInterfaceCount; ++index, ++interfaceStateP) { 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (*interfaceStateP) { 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_ADDING_1: // state 1 means it cycled during the usleep window 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_RESUMING_1: 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_ADDING_1A: 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_ADDING_2: 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_RESUMING_1A: 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_RESUMING_2: 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_REMOVING: 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville anyAsync = true; 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // At this point there are no pending asynchronous operations 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic void IObject_AbortAsyncOperation(SLObjectItf self) 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE_VOID 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Abort_internal(this); 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE_VOID 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillevoid IObject_Destroy(SLObjectItf self) 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE_VOID 521203e588e3c42a81aa8a56f595119c181a63b12caWink Saville 522203e588e3c42a81aa8a56f595119c181a63b12caWink Saville IObject *this = (IObject *) self; 523203e588e3c42a81aa8a56f595119c181a63b12caWink Saville // mutex is unlocked 524203e588e3c42a81aa8a56f595119c181a63b12caWink Saville Abort_internal(this); 525203e588e3c42a81aa8a56f595119c181a63b12caWink Saville // mutex is locked 526203e588e3c42a81aa8a56f595119c181a63b12caWink Saville const ClassTable *class__ = this->mClass; 527203e588e3c42a81aa8a56f595119c181a63b12caWink Saville PreDestroyHook preDestroy = class__->mPreDestroy; 528203e588e3c42a81aa8a56f595119c181a63b12caWink Saville // The pre-destroy hook is called with mutex locked, and should block until it is safe to 529203e588e3c42a81aa8a56f595119c181a63b12caWink Saville // destroy. It is OK to unlock the mutex temporarily, as it long as it re-locks the mutex 530203e588e3c42a81aa8a56f595119c181a63b12caWink Saville // before returning. 531203e588e3c42a81aa8a56f595119c181a63b12caWink Saville if (NULL != preDestroy) { 532203e588e3c42a81aa8a56f595119c181a63b12caWink Saville predestroy_t okToDestroy = (*preDestroy)(this); 533203e588e3c42a81aa8a56f595119c181a63b12caWink Saville switch (okToDestroy) { 534203e588e3c42a81aa8a56f595119c181a63b12caWink Saville case predestroy_ok: 535203e588e3c42a81aa8a56f595119c181a63b12caWink Saville break; 536203e588e3c42a81aa8a56f595119c181a63b12caWink Saville case predestroy_error: 537203e588e3c42a81aa8a56f595119c181a63b12caWink Saville SL_LOGE("Object::Destroy(%p) not allowed", this); 538203e588e3c42a81aa8a56f595119c181a63b12caWink Saville // fall through 5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case predestroy_again: 5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // unfortunately Destroy doesn't return a result 5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE_VOID 5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // unreachable 5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(false); 5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 54822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } 5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mState = SL_OBJECT_STATE_DESTROYING; 5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville VoidHook destroy = class__->mDestroy; 5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // const, no lock needed 5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IEngine *thisEngine = &this->mEngine->mEngine; 5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unsigned i = this->mInstanceID; 5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(MAX_INSTANCE >= i); 5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // avoid a recursive lock on the engine when destroying the engine itself 5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (thisEngine->mThis != this) { 5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville interface_lock_exclusive(thisEngine); 5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // An unpublished object has a slot reserved, but the ID hasn't been chosen yet 5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(0 < thisEngine->mInstanceCount); 5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville --thisEngine->mInstanceCount; 5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If object is published, then remove it from exposure to sync thread and debugger 5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (0 != i) { 5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville --i; 5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unsigned mask = 1 << i; 5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(thisEngine->mInstanceMask & mask); 5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville thisEngine->mInstanceMask &= ~mask; 5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(thisEngine->mInstances[i] == this); 5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville thisEngine->mInstances[i] = NULL; 5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // avoid a recursive unlock on the engine when destroying the engine itself 5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (thisEngine->mThis != this) { 5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville interface_unlock_exclusive(thisEngine); 5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The destroy hook is called with mutex locked 5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL != destroy) { 5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (*destroy)(this); 5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Call the deinitializer for each currently initialized interface, 5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // whether it is implicit, explicit, optional, or dynamically added. 5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The deinitializers are called in the reverse order that the 5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // initializers were called, so that IObject_deinit is called last. 5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unsigned index = class__->mInterfaceCount; 5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const struct iid_vtable *x = &class__->mInterfaces[index]; 5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLuint8 *interfaceStateP = &this->mInterfaceStates[index]; 5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for ( ; index > 0; --index) { 5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville --x; 5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville size_t offset = x->mOffset; 5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void *thisItf = (char *) this + offset; 5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLuint32 state = *--interfaceStateP; 5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (state) { 5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_UNINITIALIZED: 5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_EXPOSED: // quiescent states 5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_ADDED: 5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_SUSPENDED: 5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The remove hook is called with mutex locked 5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville { 599454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville VoidHook remove = MPH_init_table[x->mMPH].mRemove; 6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL != remove) { 6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (*remove)(thisItf); 60275c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao } 60375c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao *interfaceStateP = INTERFACE_INITIALIZED; 60475c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao } 60575c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao // fall through 60675c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao case INTERFACE_INITIALIZED: 60775c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao { 60875c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao VoidHook deinit = MPH_init_table[x->mMPH].mDeinit; 60975c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao if (NULL != deinit) { 61075c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao (*deinit)(thisItf); 61175c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao } 61275c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao *interfaceStateP = INTERFACE_UNINITIALIZED; 61375c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao } 61475c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao break; 61575c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao case INTERFACE_ADDING_1: // active states indicate incorrect use of API 61675c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao case INTERFACE_ADDING_1A: 61775c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao case INTERFACE_ADDING_2: 61875c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao case INTERFACE_RESUMING_1: 61975c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao case INTERFACE_RESUMING_1A: 6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_RESUMING_2: 6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_REMOVING: 6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case INTERFACE_SUSPENDING: 6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LOGE("Object::Destroy(%p) while interface %u active", this, index); 6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(SL_BOOLEAN_FALSE); 6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The mutex is unlocked and destroyed by IObject_deinit, which is the last deinitializer 6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville memset(this, 0x55, class__->mSize); // catch broken applications that continue using interfaces 6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // was ifdef USE_DEBUG but safer to do this unconditionally 6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville free(this); 6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SL_OBJECTID_ENGINE == class__->mSLObjectID) { 6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CEngine_Destroyed((CEngine *) this); 6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE_VOID 6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic SLresult IObject_SetPriority(SLObjectItf self, SLint32 priority, SLboolean preemptable) 6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE 6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#if USE_PROFILES & USE_PROFILES_BASE 6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mPriority = priority; 6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mPreemptable = SL_BOOLEAN_FALSE != preemptable; // normalize 6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#else 6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_FEATURE_UNSUPPORTED; 6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#endif 6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE 6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic SLresult IObject_GetPriority(SLObjectItf self, SLint32 *pPriority, SLboolean *pPreemptable) 6635b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam{ 6645b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam SL_ENTER_INTERFACE 665e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville 666e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville#if USE_PROFILES & USE_PROFILES_BASE 6675b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam if (NULL == pPriority || NULL == pPreemptable) { 668e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville result = SL_RESULT_PARAMETER_INVALID; 6695b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam } else { 6705b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam IObject *this = (IObject *) self; 6715b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam object_lock_shared(this); 6725b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam SLint32 priority = this->mPriority; 6735b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam SLboolean preemptable = this->mPreemptable; 6745b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam object_unlock_shared(this); 6755b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam *pPriority = priority; 6765b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam *pPreemptable = preemptable; 6775b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam result = SL_RESULT_SUCCESS; 6785b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam } 6795b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam#else 6805b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam result = SL_RESULT_FEATURE_UNSUPPORTED; 6815b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam#endif 6825b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam 683e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville SL_LEAVE_INTERFACE 6845b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam} 6855b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam 6865b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam 6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatic SLresult IObject_SetLossOfControlInterfaces(SLObjectItf self, 6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled) 6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_ENTER_INTERFACE 6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#if USE_PROFILES & USE_PROFILES_BASE 6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_SUCCESS; 69422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (0 < numInterfaces) { 6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLuint32 i; 6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL == pInterfaceIDs) { 6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_PARAMETER_INVALID; 6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject *this = (IObject *) self; 7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const ClassTable *class__ = this->mClass; 7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unsigned lossOfControlMask = 0; 7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The cast is due to a typo in the spec, bug 6482 7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (i = 0; i < (SLuint32) numInterfaces; ++i) { 7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SLInterfaceID iid = pInterfaceIDs[i]; 7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (NULL == iid) { 7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_PARAMETER_INVALID; 7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville goto out; 7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int MPH, index; 7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We ignore without error any invalid MPH or index, but spec is unclear 7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((0 <= (MPH = IID_to_MPH(iid))) && 7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // no need to check for an initialization hook 7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (NULL == MPH_init_table[MPH].mInit) || 7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (0 <= (index = class__->mMPH_to_index[MPH]))) { 7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville lossOfControlMask |= (1 << index); 7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_lock_exclusive(this); 7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (enabled) { 7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mLossOfControlMask |= lossOfControlMask; 7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mLossOfControlMask &= ~lossOfControlMask; 7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville object_unlock_exclusive(this); 7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleout: 7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#else 7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = SL_RESULT_FEATURE_UNSUPPORTED; 7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#endif 7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SL_LEAVE_INTERFACE 7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 735e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 736e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkastatic const struct SLObjectItf_ IObject_Itf = { 737e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IObject_Realize, 738e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IObject_Resume, 7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_GetState, 7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_GetInterface, 7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_RegisterCallback, 7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_AbortAsyncOperation, 7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_Destroy, 7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_SetPriority, 7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_GetPriority, 7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IObject_SetLossOfControlInterfaces, 7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}; 7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** \brief This must be the first initializer called for an object */ 7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillevoid IObject_init(void *self) 7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville IObject *this = (IObject *) self; 755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville this->mItf = &IObject_Itf; 756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // initialized in construct: 757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // mClass 758ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // mInstanceID 759ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // mLossOfControlMask 760ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // mEngine 761ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // mInterfaceStates 7625fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville this->mState = SL_OBJECT_STATE_UNREALIZED; 7635fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville this->mGottenMask = 1; // IObject 7645fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville this->mAttributesMask = 0; 7655fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville this->mCallback = NULL; 7665fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville this->mContext = NULL; 7670c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville#if USE_PROFILES & USE_PROFILES_BASE 7680c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville this->mPriority = SL_PRIORITY_NORMAL; 7690c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville this->mPreemptable = SL_BOOLEAN_FALSE; 7700c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville#endif 771bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan this->mStrongRefCount = 0; 7720c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville int ok; 7730c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville ok = pthread_mutex_init(&this->mMutex, (const pthread_mutexattr_t *) NULL); 774bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan assert(0 == ok); 7750c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville#ifdef USE_DEBUG 7760c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville memset(&this->mOwner, 0, sizeof(pthread_t)); 7770c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville this->mFile = NULL; 7785fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville this->mLine = 0; 7790c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville#endif 7800c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville ok = pthread_cond_init(&this->mCond, (const pthread_condattr_t *) NULL); 7810c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville assert(0 == ok); 7825fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville} 7835fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 7840c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville 7855fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville/** \brief This must be the last deinitializer called for an object */ 7865fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville 7875fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Savillevoid IObject_deinit(void *self) 7880c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville{ 7895fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville IObject *this = (IObject *) self; 7905fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville#ifdef USE_DEBUG 791bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan assert(pthread_equal(pthread_self(), this->mOwner)); 7925fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville#endif 793bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan int ok; 7945fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville ok = pthread_cond_destroy(&this->mCond); 795bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan assert(0 == ok); 7965fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville // equivalent to object_unlock_exclusive, but without the rigmarole 797bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan ok = pthread_mutex_unlock(&this->mMutex); 798bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan assert(0 == ok); 7995fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville ok = pthread_mutex_destroy(&this->mMutex); 8005fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville assert(0 == ok); 801ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville // redundant: this->mState = SL_OBJECT_STATE_UNREALIZED; 802ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville} 803ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville 804ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville 805ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville/** \brief Publish a new object after it is fully initialized. 806ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville * Publishing will expose the object to sync thread and debugger, 807ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville * and make it safe to return the SLObjectItf to the application. 808ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville */ 809ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville 810ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savillevoid IObject_Publish(IObject *this) 811ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville{ 8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IEngine *thisEngine = &this->mEngine->mEngine; 8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville interface_lock_exclusive(thisEngine); 81422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville // construct earlier reserved a pending slot, but did not choose the actual slot number 81522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville unsigned availMask = ~thisEngine->mInstanceMask; 816ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville assert(availMask); 8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville unsigned i = ctz(availMask); 81822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville assert(MAX_INSTANCE > i); 8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville assert(NULL == thisEngine->mInstances[i]); 82022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville thisEngine->mInstances[i] = this; 8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville thisEngine->mInstanceMask |= 1 << i; 8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // avoid zero as a valid instance ID 8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this->mInstanceID = i + 1; 824e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka interface_unlock_exclusive(thisEngine); 825e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka} 826e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka