locks.c revision d158d31a6bbb06426b71c3d097b7768bc3fb79a3
1a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten/*
2a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
3a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *
4a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * you may not use this file except in compliance with the License.
6a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * You may obtain a copy of the License at
7a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *
8a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *
10a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * See the License for the specific language governing permissions and
14a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * limitations under the License.
15a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten */
16a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
17a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten#include "sles_allinclusive.h"
18a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
20928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Exclusively lock an object */
210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
22fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG
23bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_lock_exclusive_(IObject *thiz, const char *file, int line)
24fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten{
25fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    int ok;
26bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_mutex_trylock(&thiz->mMutex);
27fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    if (0 != ok) {
284f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        // pthread_mutex_timedlock_np is not available, but wait up to 100 ms
294f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        static const useconds_t backoffs[] = {1, 10000, 20000, 30000, 40000};
304f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        unsigned i = 0;
314f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        for (;;) {
324f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten            usleep(backoffs[i]);
33bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            ok = pthread_mutex_trylock(&thiz->mMutex);
344f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten            if (0 == ok)
354f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten                break;
364f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten            if (++i >= (sizeof(backoffs) / sizeof(backoffs[0]))) {
37b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten                SL_LOGW("%s:%d: object %p was locked by %p at %s:%d\n",
38bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                    file, line, thiz, *(void **)&thiz->mOwner, thiz->mFile, thiz->mLine);
394f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten                // attempt one more time; maybe this time we will be successful
40bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                ok = pthread_mutex_lock(&thiz->mMutex);
414f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten                assert(0 == ok);
424f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten                break;
434f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten            }
444f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        }
45fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    }
46fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    pthread_t zero;
47fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten    memset(&zero, 0, sizeof(pthread_t));
48bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    if (0 != memcmp(&zero, &thiz->mOwner, sizeof(pthread_t))) {
49bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        if (pthread_equal(pthread_self(), thiz->mOwner)) {
504f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten            SL_LOGE("%s:%d: object %p was recursively locked by %p at %s:%d\n",
51bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                file, line, thiz, *(void **)&thiz->mOwner, thiz->mFile, thiz->mLine);
524f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        } else {
534f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten            SL_LOGE("%s:%d: object %p was left unlocked in unexpected state by %p at %s:%d\n",
54bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                file, line, thiz, *(void **)&thiz->mOwner, thiz->mFile, thiz->mLine);
554f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        }
564f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten        assert(false);
574f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten    }
58bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mOwner = pthread_self();
59bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mFile = file;
60bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mLine = line;
61fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten}
62fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#else
63bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_lock_exclusive(IObject *thiz)
64a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
65a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    int ok;
66bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_mutex_lock(&thiz->mMutex);
67a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    assert(0 == ok);
68a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
69fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif
70a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
72928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Exclusively unlock an object and do not report any updates */
730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
74fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG
75bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive_(IObject *thiz, const char *file, int line)
764597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{
77bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(pthread_equal(pthread_self(), thiz->mOwner));
78bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(NULL != thiz->mFile);
79bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(0 != thiz->mLine);
80bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    memset(&thiz->mOwner, 0, sizeof(pthread_t));
81bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mFile = file;
82bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mLine = line;
83a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    int ok;
84bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_mutex_unlock(&thiz->mMutex);
85a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    assert(0 == ok);
86a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
874597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#else
88bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive(IObject *thiz)
894597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{
904597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten    int ok;
91bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_mutex_unlock(&thiz->mMutex);
924597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten    assert(0 == ok);
934597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten}
944597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif
95a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
97928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Exclusively unlock an object and report updates to the specified bit-mask of
98928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten *  attributes
99928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */
1000b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
1014597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#ifdef USE_DEBUG
102bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive_attributes_(IObject *thiz, unsigned attributes,
1034597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten    const char *file, int line)
1044597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#else
105bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive_attributes(IObject *thiz, unsigned attributes)
1064597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif
107e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten{
108fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten
109fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG
110bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(pthread_equal(pthread_self(), thiz->mOwner));
111bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(NULL != thiz->mFile);
112bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(0 != thiz->mLine);
113fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif
114fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten
115e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    int ok;
116bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    SLuint32 objectID = IObjectToObjectID(thiz);
117e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    CAudioPlayer *ap;
1184b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
1194b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    // FIXME The endless if statements are getting ugly, should use bit search
1204b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
121e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    // Android likes to see certain updates synchronously
1223c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
123e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (attributes & ATTR_GAIN) {
124e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        switch (objectID) {
125e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        case SL_OBJECTID_AUDIOPLAYER:
126e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            attributes &= ~ATTR_GAIN;   // no need to process asynchronously also
127bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            ap = (CAudioPlayer *) thiz;
128e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#ifdef ANDROID
129d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi            android_audioPlayer_volumeUpdate(ap);
130e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else
131e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            audioPlayerGainUpdate(ap);
132e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#endif
133e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
134e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        case SL_OBJECTID_OUTPUTMIX:
135e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // FIXME update gains on all players attached to this outputmix
136a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten            SL_LOGD("[ FIXME: gain update on an SL_OBJECTID_OUTPUTMIX to be implemented ]");
1373c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            break;
1383c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        case SL_OBJECTID_MIDIPLAYER:
1397a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten            // MIDI
140a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten            SL_LOGD("[ FIXME: gain update on an SL_OBJECTID_MIDIPLAYER to be implemented ]");
141e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
142e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        default:
143e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            break;
144e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        }
145e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    }
1463c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
1473c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi    if (attributes & ATTR_POSITION) {
1483c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        switch (objectID) {
1493c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        case SL_OBJECTID_AUDIOPLAYER:
1503c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#ifdef ANDROID
151bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            ap = (CAudioPlayer *) thiz;
1524b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            attributes &= ~ATTR_POSITION;   // no need to process asynchronously also
153d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi            android_audioPlayer_seek(ap, ap->mSeek.mPos);
1543c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#else
1554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            //audioPlayerTransportUpdate(ap);
1563c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#endif
1573c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            break;
1583c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        case SL_OBJECTID_MIDIPLAYER:
1597a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten            // MIDI
160a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten            SL_LOGD("[ FIXME: position update on an SL_OBJECTID_MIDIPLAYER to be implemented ]");
1613c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            break;
1623c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        default:
1633c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi            break;
1643c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi        }
1653c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi    }
1663c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi
167e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (attributes & ATTR_TRANSPORT) {
16894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        switch (objectID) {
16994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        case SL_OBJECTID_AUDIOPLAYER:
1704b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef ANDROID
171e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            attributes &= ~ATTR_TRANSPORT;   // no need to process asynchronously also
172bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            ap = (CAudioPlayer *) thiz;
173e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // FIXME should only call when state changes
1748a1b7f28c1c3de212a302182022310ab7b227788Jean-Michel Trivi            android_audioPlayer_setPlayState(ap, false /*lockAP*/);
175e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            // FIXME ditto, but for either eventflags or marker position
176d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi            android_audioPlayer_useEventMask(ap);
177e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else
1784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            //audioPlayerTransportUpdate(ap);
179e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#endif
18094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            break;
18194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        case SL_OBJECTID_AUDIORECORDER:
1823b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi#ifdef ANDROID
18394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            {
1843b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi            attributes &= ~ATTR_TRANSPORT;   // no need to process asynchronously also
185bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            CAudioRecorder* ar = (CAudioRecorder *) thiz;
1863b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi            android_audioRecorder_useEventMask(ar);
18794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            }
18894a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif
18994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            break;
19094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        case XA_OBJECTID_MEDIAPLAYER:
19194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef ANDROID
19294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            {
19394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            attributes &= ~ATTR_TRANSPORT;   // no need to process asynchronously also
194bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            CMediaPlayer *mp = (CMediaPlayer *) thiz;
19568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi            android::GenericPlayer* avp = mp->mAVPlayer.get();
196f271eea20f9fff6c101213b34652399f457bcd50Jean-Michel Trivi            if (avp != NULL) {
197581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi                android_Player_setPlayState(avp, mp->mPlay.mState, &(mp->mAndroidObjState));
198f271eea20f9fff6c101213b34652399f457bcd50Jean-Michel Trivi            }
19994a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            }
2003b142e50f4ae068f50f8e3d277e0f19910c67001Jean-Michel Trivi#endif
20194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            break;
20294a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        default:
20394a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten            break;
204e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        }
205e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    }
2064b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
207d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    if (attributes & ATTR_BQ_ENQUEUE) {
208d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // ( buffer queue count is non-empty and play state == PLAYING ) became true
2094b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        if (SL_OBJECTID_AUDIOPLAYER == objectID) {
210d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            attributes &= ~ATTR_BQ_ENQUEUE;
211bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            ap = (CAudioPlayer *) thiz;
2124b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            if (SL_PLAYSTATE_PLAYING == ap->mPlay.mState) {
213b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi#ifdef ANDROID
2140ac71cb5890738ea93c26a9f567be2b523235c64Jean-Michel Trivi                android_audioPlayer_bufferQueue_onRefilled(ap);
215b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi#endif
2164b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten            }
2174b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten        }
218d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#ifndef ANDROID
2194b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten    }
220d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#else
221d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    } else if (attributes & ATTR_ABQ_ENQUEUE) {
222d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // (Android buffer queue count is non-empty and play state == PLAYING ) became true
223d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if (SL_OBJECTID_AUDIOPLAYER == objectID) {
224d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            attributes &= ~ATTR_BQ_ENQUEUE;
225d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            ap = (CAudioPlayer *) thiz;
226d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            if (SL_PLAYSTATE_PLAYING == ap->mPlay.mState) {
227d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                // FIXME notify queue refilled
228d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            }
229d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        } else if (XA_OBJECTID_MEDIAPLAYER == objectID) {
230d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            attributes &= ~ATTR_BQ_ENQUEUE;
231d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            if (SL_PLAYSTATE_PLAYING == ((CMediaPlayer*)thiz)->mPlay.mState) {
232d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                // FIXME notify queue refilled
233d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            }
234d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
235d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
236d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#endif
2374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten
238e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    if (attributes) {
239bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        unsigned oldAttributesMask = thiz->mAttributesMask;
240bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mAttributesMask = oldAttributesMask | attributes;
241e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten        if (oldAttributesMask)
242e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten            attributes = ATTR_NONE;
243e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    }
244fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG
245bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    memset(&thiz->mOwner, 0, sizeof(pthread_t));
246bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mFile = file;
247bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mLine = line;
248fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif
249bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_mutex_unlock(&thiz->mMutex);
250e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    assert(0 == ok);
251f51dba65751107c930759938775b75531ec1f330Glenn Kasten    // first update to this interface since previous sync
252f51dba65751107c930759938775b75531ec1f330Glenn Kasten    if (attributes) {
253bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        unsigned id = thiz->mInstanceID;
254f51dba65751107c930759938775b75531ec1f330Glenn Kasten        if (0 != id) {
255f51dba65751107c930759938775b75531ec1f330Glenn Kasten            --id;
256f51dba65751107c930759938775b75531ec1f330Glenn Kasten            assert(MAX_INSTANCE > id);
257bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            IEngine *thisEngine = &thiz->mEngine->mEngine;
258f51dba65751107c930759938775b75531ec1f330Glenn Kasten            interface_lock_exclusive(thisEngine);
259f51dba65751107c930759938775b75531ec1f330Glenn Kasten            thisEngine->mChangedMask |= 1 << id;
260f51dba65751107c930759938775b75531ec1f330Glenn Kasten            interface_unlock_exclusive(thisEngine);
261f51dba65751107c930759938775b75531ec1f330Glenn Kasten        }
262e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    }
263e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten}
264e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten
2650b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
266928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Wait on the condition variable associated with the object; see pthread_cond_wait */
2670b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
2684f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#ifdef USE_DEBUG
269bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_wait_(IObject *thiz, const char *file, int line)
2704f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten{
2714f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten    // note that this will unlock the mutex, so we have to clear the owner
272bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(pthread_equal(pthread_self(), thiz->mOwner));
273bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(NULL != thiz->mFile);
274bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    assert(0 != thiz->mLine);
275bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    memset(&thiz->mOwner, 0, sizeof(pthread_t));
276bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mFile = file;
277bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mLine = line;
2784f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten    // alas we don't know the new owner's identity
2794f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten    int ok;
280bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_cond_wait(&thiz->mCond, &thiz->mMutex);
2814f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten    assert(0 == ok);
2824f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten    // restore my ownership
283bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mOwner = pthread_self();
284bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mFile = file;
285bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mLine = line;
2864f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten}
2874f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#else
288bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_wait(IObject *thiz)
289a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
290a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    int ok;
291bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_cond_wait(&thiz->mCond, &thiz->mMutex);
292a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    assert(0 == ok);
293a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
2944f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#endif
295a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
2960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
297928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Signal the condition variable associated with the object; see pthread_cond_signal */
2980b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
299bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_signal(IObject *thiz)
300a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
301a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    int ok;
302bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_cond_signal(&thiz->mCond);
303a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    assert(0 == ok);
304a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
305a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten
3060b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
307928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Broadcast the condition variable associated with the object;
308928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten *  see pthread_cond_broadcast
309928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */
3100b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten
311bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_broadcast(IObject *thiz)
312a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten{
313a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten    int ok;
314bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ok = pthread_cond_broadcast(&thiz->mCond);
315a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten    assert(0 == ok);
316a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten}
317