IObject.c revision 8c065779232fdd89abace68d2fc7bea786a010d7
161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* 261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * 461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * you may not use this file except in compliance with the License. 661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * You may obtain a copy of the License at 761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * 861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * 1061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * Unless required by applicable law or agreed to in writing, software 1161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 1261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * See the License for the specific language governing permissions and 1461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten * limitations under the License. 1561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten */ 1661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 1761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten/* Object implementation */ 1861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 1961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten#include "sles_allinclusive.h" 2061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 22510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten// Called by a worker thread to handle an asynchronous Object.Realize. 23510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten// Parameter self is the Object. 24d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 25510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenstatic void HandleRealize(void *self, int unused) 2661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 27510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 28510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // validate input parameters 29510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten IObject *this = (IObject *) self; 30510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(NULL != this); 3161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const ClassTable *class__ = this->mClass; 32510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(NULL != class__); 333d146e0a31f5ee2a7d9807c4e99994084fdd3283Jean-Michel Trivi AsyncHook realize = class__->mRealize; 343a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten SLresult result; 35276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 36510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 37510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // check object state 3861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_lock_exclusive(this); 39510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = this->mState; 40510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten switch (state) { 41510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 42510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case SL_OBJECT_STATE_REALIZING_1: // normal case 43510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten if (NULL != realize) { 44510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten this->mState = SL_OBJECT_STATE_REALIZING_2; 45510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_exclusive(this); 46510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Note that the mutex is unlocked during the realize hook 47510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = (*realize)(this, SL_BOOLEAN_TRUE); 48510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_lock_exclusive(this); 49510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(SL_OBJECT_STATE_REALIZING_2 == this->mState); 50510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = SL_RESULT_SUCCESS == result ? SL_OBJECT_STATE_REALIZED : 51510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SL_OBJECT_STATE_UNREALIZED; 52510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else { 53510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = SL_RESULT_SUCCESS; 54510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = SL_OBJECT_STATE_REALIZED; 55510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 56510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 57510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 58510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case SL_OBJECT_STATE_REALIZING_1A: // operation was aborted while on work queue 59510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = SL_RESULT_OPERATION_ABORTED; 60510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = SL_OBJECT_STATE_UNREALIZED; 61510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 62510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 63510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten default: // impossible 64510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(SL_BOOLEAN_FALSE); 65510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = SL_RESULT_INTERNAL_ERROR; 66510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 67510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 6861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 69510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 70510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // mutex is locked, update state 71d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten this->mState = state; 72510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 73d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten // Make a copy of these, so we can call the callback with mutex unlocked 74d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten slObjectCallback callback = this->mCallback; 75d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten void *context = this->mContext; 7661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_unlock_exclusive(this); 77510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 78d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten // Note that the mutex is unlocked during the callback 798c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (NULL != callback) { 80d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten (*callback)(&this->mItf, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, NULL); 818c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 82d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} 83d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 84ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 85d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IObject_Realize(SLObjectItf self, SLboolean async) 86d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten{ 87ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 88ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 89d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten IObject *this = (IObject *) self; 90276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 91d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten const ClassTable *class__ = this->mClass; 92d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten object_lock_exclusive(this); 93d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten state = this->mState; 94d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten // Reject redundant calls to Realize 95d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten if (SL_OBJECT_STATE_UNREALIZED != state) { 96510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_exclusive(this); 97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 98d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } else { 99ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Asynchronous: mark operation pending and cancellable 100ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (async && (SL_OBJECTID_ENGINE != class__->mObjectID)) { 101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = SL_OBJECT_STATE_REALIZING_1; 102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Synchronous: mark operation pending and non-cancellable 103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = SL_OBJECT_STATE_REALIZING_2; 105d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 106d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten this->mState = state; 107d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten object_unlock_exclusive(this); 108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten switch (state) { 109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_REALIZING_1: // asynchronous on non-Engine 110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(async); 111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = ThreadPool_add(&this->mEngine->mThreadPool, HandleRealize, this, 0); 112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS != result) { 113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Engine was destroyed during realize, or insufficient memory 114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_exclusive(this); 115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mState = SL_OBJECT_STATE_UNREALIZED; 116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_exclusive(this); 117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_REALIZING_2: // synchronous, or asynchronous on Engine 120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten { 121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten AsyncHook realize = class__->mRealize; 122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Note that the mutex is unlocked during the realize hook 123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = (NULL != realize) ? (*realize)(this, async) : SL_RESULT_SUCCESS; 124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_exclusive(this); 125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_OBJECT_STATE_REALIZING_2 == this->mState); 126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = (SL_RESULT_SUCCESS == result) ? SL_OBJECT_STATE_REALIZED : 127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_OBJECT_STATE_UNREALIZED; 128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mState = state; 129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten slObjectCallback callback = this->mCallback; 130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten void *context = this->mContext; 131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_exclusive(this); 132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // asynchronous Realize on an Engine is actually done synchronously, but still has 133ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // callback because there is no thread pool yet to do it asynchronously. 1348c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (async && (NULL != callback)) { 135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten (*callback)(&this->mItf, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, 136ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten NULL); 137ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1388c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten default: // impossible 141ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_BOOLEAN_FALSE); 142ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 143d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 144d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 14761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 14861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 150510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten// Called by a worker thread to handle an asynchronous Object.Resume. 151510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten// Parameter self is the Object. 152510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 153510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenstatic void HandleResume(void *self, int unused) 15461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 155510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 156510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // valid input parameters 15761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject *this = (IObject *) self; 158510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(NULL != this); 15961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const ClassTable *class__ = this->mClass; 160510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(NULL != class__); 161510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten AsyncHook resume = class__->mResume; 1623a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten SLresult result; 163276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 164510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 165510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // check object state 16661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_lock_exclusive(this); 167510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = this->mState; 168510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten switch (state) { 169510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 170510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case SL_OBJECT_STATE_RESUMING_1: // normal case 171510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten if (NULL != resume) { 172510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten this->mState = SL_OBJECT_STATE_RESUMING_2; 173510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_exclusive(this); 174510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Note that the mutex is unlocked during the resume hook 175510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = (*resume)(this, SL_BOOLEAN_TRUE); 176510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_lock_exclusive(this); 177510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(SL_OBJECT_STATE_RESUMING_2 == this->mState); 178510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = SL_RESULT_SUCCESS == result ? SL_OBJECT_STATE_REALIZED : 179510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SL_OBJECT_STATE_SUSPENDED; 180510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else { 181510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = SL_RESULT_SUCCESS; 182510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = SL_OBJECT_STATE_REALIZED; 1833a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten } 184510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 185510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 186510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case SL_OBJECT_STATE_RESUMING_1A: // operation was aborted while on work queue 187510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = SL_RESULT_OPERATION_ABORTED; 188510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = SL_OBJECT_STATE_SUSPENDED; 189510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 190510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 191510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten default: // impossible 192510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(SL_BOOLEAN_FALSE); 193510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten result = SL_RESULT_INTERNAL_ERROR; 194510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 195510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 19661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 197510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 198510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // mutex is unlocked, update state 199510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten this->mState = state; 200510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 201510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Make a copy of these, so we can call the callback with mutex unlocked 202510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten slObjectCallback callback = this->mCallback; 203510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten void *context = this->mContext; 20461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_unlock_exclusive(this); 205510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 206510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Note that the mutex is unlocked during the callback 2078c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (NULL != callback) { 208510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten (*callback)(&this->mItf, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, NULL); 2098c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 210510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten} 211510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 213510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenstatic SLresult IObject_Resume(SLObjectItf self, SLboolean async) 214510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten{ 215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 217510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten IObject *this = (IObject *) self; 218510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten const ClassTable *class__ = this->mClass; 219276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten SLuint8 state; 220510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_lock_exclusive(this); 221510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten state = this->mState; 222510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Reject redundant calls to Resume 223510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten if (SL_OBJECT_STATE_SUSPENDED != state) { 224510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_exclusive(this); 225ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 226510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else { 227ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Asynchronous: mark operation pending and cancellable 228ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (async) { 229ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = SL_OBJECT_STATE_RESUMING_1; 230ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Synchronous: mark operatio pending and non-cancellable 231ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 232ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = SL_OBJECT_STATE_RESUMING_2; 233510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 234ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mState = state; 235510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_exclusive(this); 236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten switch (state) { 237ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_RESUMING_1: // asynchronous 238ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(async); 239ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = ThreadPool_add(&this->mEngine->mThreadPool, HandleResume, this, 0); 240ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS != result) { 241ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Engine was destroyed during resume, or insufficient memory 242ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_exclusive(this); 243ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mState = SL_OBJECT_STATE_SUSPENDED; 244ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_exclusive(this); 245ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 246ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 247ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_RESUMING_2: // synchronous 248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten { 249ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten AsyncHook resume = class__->mResume; 250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Note that the mutex is unlocked during the resume hook 251ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = (NULL != resume) ? (*resume)(this, SL_BOOLEAN_FALSE) : SL_RESULT_SUCCESS; 252ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_exclusive(this); 253ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_OBJECT_STATE_RESUMING_2 == this->mState); 254ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mState = (SL_RESULT_SUCCESS == result) ? SL_OBJECT_STATE_REALIZED : 255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_OBJECT_STATE_SUSPENDED; 256ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_exclusive(this); 257ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 258ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 259ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten default: // impossible 260ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_BOOLEAN_FALSE); 261ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 262510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 263510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 264ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 265ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 26661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 26761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 268ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 26961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_GetState(SLObjectItf self, SLuint32 *pState) 27061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 271ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 272ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 273ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pState) { 274ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 275ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 276ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IObject *this = (IObject *) self; 277ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Note that the state is immediately obsolete, so a peek lock is safe 278ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_peek(this); 279ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLuint8 state = this->mState; 280ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_peek(this); 281ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Re-map the realizing, resuming, and suspending states 282ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten switch (state) { 283ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_REALIZING_1: 284ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_REALIZING_1A: 285ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_REALIZING_2: 286ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = SL_OBJECT_STATE_UNREALIZED; 287ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_RESUMING_1: 289ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_RESUMING_1A: 290ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_RESUMING_2: 291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_SUSPENDING: 292ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten state = SL_OBJECT_STATE_SUSPENDED; 293ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 294ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_UNREALIZED: 295ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_REALIZED: 296ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case SL_OBJECT_STATE_SUSPENDED: 297ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // These are the "official" object states, return them as is 298ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 299ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten default: 300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten assert(SL_BOOLEAN_FALSE); 301ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 302ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 303ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pState = state; 304ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 305d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten } 306ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 307ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 30861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 30961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 310ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3113a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IObject_GetInterface(SLObjectItf self, const SLInterfaceID iid, void *pInterface) 31261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 313ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 314ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 315ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pInterface) { 31661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten result = SL_RESULT_PARAMETER_INVALID; 317ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 318ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten void *interface = NULL; 319ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == iid) { 320ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 321510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else { 322ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IObject *this = (IObject *) self; 323ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *class__ = this->mClass; 324ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten int MPH, index; 325ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if ((0 > (MPH = IID_to_MPH(iid))) || (0 > (index = class__->mMPH_to_index[MPH]))) { 326ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 327510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } else { 328ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned mask = 1 << index; 329ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_exclusive(this); 330ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Can't get interface on a suspended/suspending/resuming object 331ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_OBJECT_STATE_REALIZED != this->mState) { 332ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 333ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 334ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten switch (this->mInterfaceStates[index]) { 335ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case INTERFACE_EXPOSED: 336ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten case INTERFACE_ADDED: 337e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten interface = (char *) this + class__->mInterfaces[index].mOffset; 338ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Note that interface has been gotten, 339ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // for debugger and to detect incorrect use of interfaces 340e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten if (!(this->mGottenMask & mask)) { 341e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten this->mGottenMask |= mask; 342e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten ((size_t *) interface)[0] ^= ~0; 343e5d006b298ce7683d66f7ec86136403cf5fb20d6Glenn Kasten } 344ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 345ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 346ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // Can't get interface if uninitialized/suspend(ed,ing)/resuming/adding/removing 347ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten default: 348ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 349ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten break; 350ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 351510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 352ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_exclusive(this); 35361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 35461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 355ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *(void **)pInterface = interface; 35661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 357ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 358ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 35961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 36061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 361ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 36261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_RegisterCallback(SLObjectItf self, 36361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten slObjectCallback callback, void *pContext) 36461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 365ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 366ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 36761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject *this = (IObject *) self; 36861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_lock_exclusive(this); 36961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mCallback = callback; 37061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mContext = pContext; 37161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_unlock_exclusive(this); 372ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 373ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 374ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 37561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 37661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 377ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 378510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten// internal common code for Abort and Destroy 379510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 380510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenstatic void Abort_internal(IObject *this, SLboolean shutdown) 381510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten{ 382510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten const ClassTable *class__ = this->mClass; 383510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_lock_exclusive(this); 384510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Abort asynchronous operations on the object 385510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten switch (this->mState) { 386510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case SL_OBJECT_STATE_REALIZING_1: // Realize 387510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten this->mState = SL_OBJECT_STATE_REALIZING_1A; 388510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 389510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case SL_OBJECT_STATE_RESUMING_1: // Resume 390510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten this->mState = SL_OBJECT_STATE_RESUMING_1A; 391510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 392510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten default: 393510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 394510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 395510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // Abort asynchronous operations on interfaces 396510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten SLuint8 *interfaceStateP = this->mInterfaceStates; 397510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten unsigned index; 398510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten for (index = 0; index < class__->mInterfaceCount; ++index, ++interfaceStateP) { 399510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten switch (*interfaceStateP) { 400510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_ADDING_1: // AddInterface 401510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten *interfaceStateP = INTERFACE_ADDING_1A; 402510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 403510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_RESUMING_1: // ResumeInterface 404510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten *interfaceStateP = INTERFACE_RESUMING_1A; 405510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 406510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten default: 407510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 408510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 409510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 410510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten object_unlock_exclusive(this); 411510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten} 412510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten 413ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 41461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic void IObject_AbortAsyncOperation(SLObjectItf self) 41561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 416ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE_VOID 417ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 418510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten IObject *this = (IObject *) self; 419510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten Abort_internal(this, SL_BOOLEAN_FALSE); 420ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 421ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE_VOID 42261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 42361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 424ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 42561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic void IObject_Destroy(SLObjectItf self) 42661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 427ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE_VOID 428ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 42961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject *this = (IObject *) self; 430510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten Abort_internal(this, SL_BOOLEAN_TRUE); 43161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten const ClassTable *class__ = this->mClass; 43261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten VoidHook destroy = class__->mDestroy; 433ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // const, no lock needed 434ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten IEngine *thisEngine = this->mEngine; 435ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten unsigned i = this->mInstanceID; 436d07ed7df4ec9338f97f12627690d58ed9b34f25bGlenn Kasten assert(0 < i && i <= MAX_INSTANCE); 437ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten --i; 438510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // remove object from exposure to sync thread and debugger 439ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_lock_exclusive(thisEngine); 440ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten assert(0 < thisEngine->mInstanceCount); 441ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten --thisEngine->mInstanceCount; 442ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten assert(0 != thisEngine->mInstanceMask); 443ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten thisEngine->mInstanceMask &= ~(1 << i); 444ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten assert(thisEngine->mInstances[i] == this); 445ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten thisEngine->mInstances[i] = NULL; 44600d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#ifdef USE_SDL 4478c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // FIXME put this into the output mix destroy callback 448e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if ((SL_OBJECTID_OUTPUTMIX == class__->mObjectID) && 449e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten (((COutputMix *) this == thisEngine->mOutputMix))) { 45000d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten SDL_PauseAudio(1); 45100d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten thisEngine->mOutputMix = NULL; 45200d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten // Note we don't attempt to connect another output mix to SDL 45300d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten } 45400d2d554e04ac369367c903dbf53b975355d1bcdGlenn Kasten#endif 455ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten interface_unlock_exclusive(thisEngine); 45661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_lock_exclusive(this); 4578c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (NULL != destroy) { 458d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten (*destroy)(this); 4598c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 46061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten // Call the deinitializer for each currently exposed interface, 46161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten // whether it is implicit, explicit, optional, or dynamically added. 4624597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten // The deinitializers are called in the reverse order that the 4634597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten // initializers were called, so that IObject_deinit is called last. 464510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten unsigned incorrect = 0; 4654597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten unsigned index = class__->mInterfaceCount; 4664597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten const struct iid_vtable *x = &class__->mInterfaces[index]; 4674597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten SLuint8 *interfaceStateP = &this->mInterfaceStates[index]; 4684597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten for ( ; index > 0; --index) { 4694597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten --x; 4704597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten SLuint32 state = *--interfaceStateP; 471510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten switch (state) { 472510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_UNINITIALIZED: 473510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 474510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_EXPOSED: // quiescent states 475510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_ADDED: 476510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_SUSPENDED: 477510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten { 47861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten VoidHook deinit = MPH_init_table[x->mMPH].mDeinit; 4798c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (NULL != deinit) { 48061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten (*deinit)((char *) this + x->mOffset); 481510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten } 4828c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 483510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 484510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_ADDING_1: // active states indicate incorrect use of API 485510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_ADDING_1A: 486510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_ADDING_2: 487510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_RESUMING_1: 488510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_RESUMING_1A: 489510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_RESUMING_2: 490510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_REMOVING: 491510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten case INTERFACE_SUSPENDING: 492510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten ++incorrect; 493510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 494510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten default: 495510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(SL_BOOLEAN_FALSE); 496510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten break; 49761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 49861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 4994597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten // The mutex is unlocked and destroyed by IObject_deinit, which is the last deinitializer 500fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 50161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten memset(this, 0x55, class__->mSize); 50261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten#endif 50361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten free(this); 504510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // one or more interfaces was actively changing at time of Destroy 505510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten assert(incorrect == 0); 506ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 507ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE_VOID 50861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 50961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 510ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 5113a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IObject_SetPriority(SLObjectItf self, SLint32 priority, SLboolean preemptable) 51261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 513ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 514ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 515c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten#ifdef USE_BASE 51661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject *this = (IObject *) self; 51761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_lock_exclusive(this); 51861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mPriority = priority; 519d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten this->mPreemptable = SL_BOOLEAN_FALSE != preemptable; // normalize 52061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten object_unlock_exclusive(this); 521ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 5227a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 5237a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 5247a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 525ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 526ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 52761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 52861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 529ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 5303a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IObject_GetPriority(SLObjectItf self, SLint32 *pPriority, SLboolean *pPreemptable) 53161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 532ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 533ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 534c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten#ifdef USE_BASE 535ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pPriority || NULL == pPreemptable) { 536ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 537ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 538ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IObject *this = (IObject *) self; 539ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_shared(this); 540ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLint32 priority = this->mPriority; 541ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLboolean preemptable = this->mPreemptable; 542ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_shared(this); 543ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pPriority = priority; 544ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pPreemptable = preemptable; 545ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 546ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 5477a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 5487a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 5497a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 550ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 551ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 55261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 55361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 554ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 55561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_SetLossOfControlInterfaces(SLObjectItf self, 55661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled) 55761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 558ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 559ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 560c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten#ifdef USE_BASE 561ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 56261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten if (0 < numInterfaces) { 56361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten SLuint32 i; 564ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pInterfaceIDs) { 565ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 566ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 567ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten IObject *this = (IObject *) self; 568ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten const ClassTable *class__ = this->mClass; 569ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten unsigned lossOfControlMask = 0; 5707a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // The cast is due to a typo in the spec, bug 6482 571ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten for (i = 0; i < (SLuint32) numInterfaces; ++i) { 572ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLInterfaceID iid = pInterfaceIDs[i]; 573ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == iid) { 574ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 575ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten goto out; 576ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 577ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten int MPH, index; 5787a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // We ignore without error any invalid MPH or index, but spec is unclear 579ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if ((0 <= (MPH = IID_to_MPH(iid))) && (0 <= (index = class__->mMPH_to_index[MPH]))) 580ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten lossOfControlMask |= (1 << index); 581ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 582ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_lock_exclusive(this); 5838c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (enabled) { 584ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mLossOfControlMask |= lossOfControlMask; 5858c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } else { 586ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten this->mLossOfControlMask &= ~lossOfControlMask; 5878c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 588ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten object_unlock_exclusive(this); 58961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 59061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten } 591ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kastenout: 5927a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#else 5937a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 5947a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 595ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 596ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 59761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 59861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 599ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 60061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic const struct SLObjectItf_ IObject_Itf = { 60161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_Realize, 60261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_Resume, 60361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_GetState, 60461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_GetInterface, 60561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_RegisterCallback, 60661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_AbortAsyncOperation, 60761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_Destroy, 60861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_SetPriority, 60961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_GetPriority, 61061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject_SetLossOfControlInterfaces, 61161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}; 61261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten 6134597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten 6144597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten/** \brief This must be the first initializer called for an object */ 6154597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten 61661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenvoid IObject_init(void *self) 61761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{ 61861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten IObject *this = (IObject *) self; 61961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mItf = &IObject_Itf; 6200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // initialized in construct: 6210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // mClass 622ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // mInstanceID 6230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten // mLossOfControlMask 624ccdf07b17f23b4c040dd3f62478d0965eba804e3Glenn Kasten // mEngine 625510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten // mInstanceStates 62661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mState = SL_OBJECT_STATE_UNREALIZED; 627510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten this->mGottenMask = 1; // IObject 628e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten this->mAttributesMask = 0; 62961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mCallback = NULL; 63061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mContext = NULL; 631c3845706778edec308bd9ced559cec0a456608bdGlenn Kasten#ifdef USE_BASE 632d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten this->mPriority = SL_PRIORITY_NORMAL; 63361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten this->mPreemptable = SL_BOOLEAN_FALSE; 6347a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten#endif 63561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten int ok; 63661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ok = pthread_mutex_init(&this->mMutex, (const pthread_mutexattr_t *) NULL); 63761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten assert(0 == ok); 638fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 639fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 640fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mFile = NULL; 641fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mLine = 0; 642fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 64361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten ok = pthread_cond_init(&this->mCond, (const pthread_condattr_t *) NULL); 64461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten assert(0 == ok); 64561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten} 6464597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten 6474597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten 6484597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten/** \brief This must be the last deinitializer called for an object */ 6494597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten 6504597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenvoid IObject_deinit(void *self) 6514597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{ 6524597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten IObject *this = (IObject *) self; 6534597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#ifdef USE_DEBUG 6544597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 6554597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif 6564597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten int ok; 6574597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten ok = pthread_cond_destroy(&this->mCond); 6584597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten assert(0 == ok); 6594597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten // equivalent to object_unlock_exclusive, but without the rigmarole 6604597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 6614597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten assert(0 == ok); 6624597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten ok = pthread_mutex_destroy(&this->mMutex); 6634597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten assert(0 == ok); 6644597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten // redundant: this->mState = SL_OBJECT_STATE_UNREALIZED; 6654597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten} 666