IObject.c revision 3a413f1863daa026ed2b9fc9eac01e1341116cdb
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
2161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_Realize(SLObjectItf self, SLboolean async)
2261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
2361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
2461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const ClassTable *class__ = this->mClass;
253d146e0a31f5ee2a7d9807c4e99994084fdd3283Jean-Michel Trivi    AsyncHook realize = class__->mRealize;
263a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    SLresult result;
273a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    slObjectCallback callback = NULL;
283a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    void *context = NULL;
293a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    SLuint32 state = 0;
3061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_lock_exclusive(this);
3161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (SL_OBJECT_STATE_UNREALIZED != this->mState) {
3261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
3361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    } else {
343a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        // FIXME The realize hook and callback should be asynchronous if requested
353a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        result = NULL != realize ? (*realize)(this, async) : SL_RESULT_SUCCESS;
3661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        if (SL_RESULT_SUCCESS == result)
3761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            this->mState = SL_OBJECT_STATE_REALIZED;
383a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        // Make a copy of these, so we can call the callback with mutex unlocked
393a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        if (async) {
403a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten            callback = this->mCallback;
413a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten            context = this->mContext;
423a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten            state = this->mState;
433a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        }
4461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    }
4561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_unlock_exclusive(this);
463a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    if (NULL != callback)
473a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        (*callback)(self, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, NULL);
4861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return result;
4961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
5061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
5161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_Resume(SLObjectItf self, SLboolean async)
5261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
5361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
5461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const ClassTable *class__ = this->mClass;
553a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    StatusHook resume = class__->mResume;
563a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    SLresult result;
573a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    slObjectCallback callback = NULL;
583a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    void *context = NULL;
593a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    SLuint32 state = 0;
6061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_lock_exclusive(this);
6161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (SL_OBJECT_STATE_SUSPENDED != this->mState) {
6261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        result = SL_RESULT_PRECONDITIONS_VIOLATED;
6361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    } else {
643a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        // FIXME The resume hook and callback should be asynchronous if requested
653a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        result = NULL != resume ? (*resume)(this) : SL_RESULT_SUCCESS;
6661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        if (SL_RESULT_SUCCESS == result)
6761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            this->mState = SL_OBJECT_STATE_REALIZED;
683a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        // Make a copy of these, so we can call the callback with mutex unlocked
693a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        if (async) {
703a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten            callback = this->mCallback;
713a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten            context = this->mContext;
723a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten            state = this->mState;
733a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        }
7461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    }
7561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_unlock_exclusive(this);
763a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    if (NULL != callback)
773a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten        (*callback)(self, context, SL_OBJECT_EVENT_ASYNC_TERMINATION, result, state, NULL);
7861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return result;
7961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
8061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
8161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_GetState(SLObjectItf self, SLuint32 *pState)
8261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
8361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == pState)
8461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
8561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
863a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    // Note that the state is immediately obsolete, so a peek lock is safe
873a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    object_lock_peek(this);
8861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLuint32 state = this->mState;
893a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    object_unlock_peek(this);
9061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *pState = state;
9161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
9261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
9361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
943a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IObject_GetInterface(SLObjectItf self, const SLInterfaceID iid, void *pInterface)
9561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
9661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == pInterface)
9761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
9861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLresult result;
9961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    void *interface = NULL;
10061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == iid)
10161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
10261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    else {
10361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        IObject *this = (IObject *) self;
10461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        const ClassTable *class__ = this->mClass;
10561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        int MPH, index;
10661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        if ((0 > (MPH = IID_to_MPH(iid))) ||
10761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            (0 > (index = class__->mMPH_to_index[MPH])))
10861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            result = SL_RESULT_FEATURE_UNSUPPORTED;
10961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        else {
11061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            unsigned mask = 1 << index;
11161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            object_lock_shared(this);
11261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            if (SL_OBJECT_STATE_REALIZED != this->mState)
11361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                result = SL_RESULT_PRECONDITIONS_VIOLATED;
11461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            else if (!(this->mExposedMask & mask))
11561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                result = SL_RESULT_FEATURE_UNSUPPORTED;
11661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            else {
11761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                // FIXME Should note that interface has been gotten,
11861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                // so as to detect use of ill-gotten interfaces; be sure
11961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                // to change the lock to exclusive if that is done
12061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                interface = (char *) this + class__->mInterfaces[index].mOffset;
12161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                result = SL_RESULT_SUCCESS;
12261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            }
12361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            object_unlock_shared(this);
12461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        }
12561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    }
12661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *(void **)pInterface = interface;
12761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
12861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
12961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
13061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_RegisterCallback(SLObjectItf self,
13161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    slObjectCallback callback, void *pContext)
13261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
13361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
13461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_lock_exclusive(this);
13561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mCallback = callback;
13661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mContext = pContext;
13761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_unlock_exclusive(this);
13861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
13961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
14061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
14161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic void IObject_AbortAsyncOperation(SLObjectItf self)
14261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
14361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    // FIXME Asynchronous operations are not yet implemented
14461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
14561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
14661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic void IObject_Destroy(SLObjectItf self)
14761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
1483a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    // FIXME The abort should be atomic w.r.t. destroy, so another async can't be started in window
14961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_AbortAsyncOperation(self);
15061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
15161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const ClassTable *class__ = this->mClass;
15261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    VoidHook destroy = class__->mDestroy;
15361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    const struct iid_vtable *x = class__->mInterfaces;
15461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_lock_exclusive(this);
15561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    // Call the deinitializer for each currently exposed interface,
15661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    // whether it is implicit, explicit, optional, or dynamically added.
15761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    unsigned exposedMask = this->mExposedMask;
15861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    for ( ; exposedMask; exposedMask >>= 1, ++x) {
15961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        if (exposedMask & 1) {
16061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            VoidHook deinit = MPH_init_table[x->mMPH].mDeinit;
16161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            if (NULL != deinit)
16261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                (*deinit)((char *) this + x->mOffset);
16361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        }
16461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    }
16561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL != destroy)
16661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        (*destroy)(this);
16761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    // redundant: this->mState = SL_OBJECT_STATE_UNREALIZED;
16861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_unlock_exclusive(this);
16961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten#ifndef NDEBUG
17061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    memset(this, 0x55, class__->mSize);
17161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten#endif
17261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    free(this);
17361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
17461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
1753a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IObject_SetPriority(SLObjectItf self, SLint32 priority, SLboolean preemptable)
17661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
17761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
17861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_lock_exclusive(this);
17961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mPriority = priority;
18061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mPreemptable = preemptable;
18161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_unlock_exclusive(this);
18261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
18361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
18461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
1853a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IObject_GetPriority(SLObjectItf self, SLint32 *pPriority, SLboolean *pPreemptable)
18661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
18761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (NULL == pPriority || NULL == pPreemptable)
18861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        return SL_RESULT_PARAMETER_INVALID;
18961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
19061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_lock_shared(this);
19161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLint32 priority = this->mPriority;
19261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLboolean preemptable = this->mPreemptable;
19361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    object_unlock_shared(this);
19461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *pPriority = priority;
19561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    *pPreemptable = preemptable;
19661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
19761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
19861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
19961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic SLresult IObject_SetLossOfControlInterfaces(SLObjectItf self,
20061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    SLint16 numInterfaces, SLInterfaceID *pInterfaceIDs, SLboolean enabled)
20161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
20261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    if (0 < numInterfaces) {
20361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        SLuint32 i;
20461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        if (NULL == pInterfaceIDs)
20561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
20661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        IObject *this = (IObject *) self;
20761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        const ClassTable *class__ = this->mClass;
20861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        unsigned lossOfControlMask = 0;
20961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        // FIXME The cast is due to a typo in the spec
21061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        for (i = 0; i < (SLuint32) numInterfaces; ++i) {
21161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            SLInterfaceID iid = pInterfaceIDs[i];
21261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            if (NULL == iid)
21361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                return SL_RESULT_PARAMETER_INVALID;
21461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            int MPH, index;
21561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            if (0 <= (MPH = IID_to_MPH(iid)) &&
21661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                (0 <= (index = class__->mMPH_to_index[MPH])))
21761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten                lossOfControlMask |= (1 << index);
21861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        }
21961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        object_lock_exclusive(this);
22061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        if (enabled)
22161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            this->mLossOfControlMask |= lossOfControlMask;
22261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        else
22361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten            this->mLossOfControlMask &= ~lossOfControlMask;
22461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten        object_unlock_exclusive(this);
22561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    }
22661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    return SL_RESULT_SUCCESS;
22761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
22861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
22961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenstatic const struct SLObjectItf_ IObject_Itf = {
23061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_Realize,
23161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_Resume,
23261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_GetState,
23361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_GetInterface,
23461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_RegisterCallback,
23561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_AbortAsyncOperation,
23661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_Destroy,
23761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_SetPriority,
23861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_GetPriority,
23961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject_SetLossOfControlInterfaces,
24061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten};
24161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten
24261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kastenvoid IObject_init(void *self)
24361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten{
24461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    IObject *this = (IObject *) self;
24561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mItf = &IObject_Itf;
2460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // initialized in construct:
2470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // mClass
2480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // mExposedMask
2490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // mLossOfControlMask
25061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mState = SL_OBJECT_STATE_UNREALIZED;
25161ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mCallback = NULL;
25261ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mContext = NULL;
25361ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mPriority = 0;
25461ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    this->mPreemptable = SL_BOOLEAN_FALSE;
25561ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    int ok;
25661ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    ok = pthread_mutex_init(&this->mMutex, (const pthread_mutexattr_t *) NULL);
25761ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    assert(0 == ok);
25861ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    ok = pthread_cond_init(&this->mCond, (const pthread_condattr_t *) NULL);
25961ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten    assert(0 == ok);
26061ac0ade16f84d877dfd8d0e984eb203d4a2901dGlenn Kasten}
261