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