locks.c revision 4f064c143ef2b26347130a49788116b5d2e1252a
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 200b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Exclusively lock an object */ 210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 22fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 23fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kastenvoid object_lock_exclusive_(IObject *this, const char *file, int line) 24fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten{ 25fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten int ok; 26fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten ok = pthread_mutex_trylock(&this->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]); 334f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten ok = pthread_mutex_trylock(&this->mMutex); 344f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten if (0 == ok) 354f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten break; 364f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten if (++i >= (sizeof(backoffs) / sizeof(backoffs[0]))) { 374f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten SL_LOGE("%s:%d: object %p was locked by %p at %s:%d\n", 384f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten file, line, this, *(void **)&this->mOwner, this->mFile, this->mLine); 394f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // attempt one more time; maybe this time we will be successful 404f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten ok = pthread_mutex_lock(&this->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)); 484f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten if (0 != memcmp(&zero, &this->mOwner, sizeof(pthread_t))) { 494f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten if (pthread_equal(pthread_self(), this->mOwner)) { 504f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten SL_LOGE("%s:%d: object %p was recursively locked by %p at %s:%d\n", 514f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten file, line, this, *(void **)&this->mOwner, this->mFile, this->mLine); 524f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } else { 534f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten SL_LOGE("%s:%d: object %p was left unlocked in unexpected state by %p at %s:%d\n", 544f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten file, line, this, *(void **)&this->mOwner, this->mFile, this->mLine); 554f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } 564f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(false); 574f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } 58fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(NULL == this->mFile); 59fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(0 == this->mLine); 60fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mOwner = pthread_self(); 61fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mFile = file; 62fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mLine = line; 63fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten} 64fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#else 654f064c143ef2b26347130a49788116b5d2e1252aGlenn Kastenvoid object_lock_exclusive(IObject *this) 66a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 67a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 68a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_mutex_lock(&this->mMutex); 69a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 70a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 71fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 72a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 740b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Exclusively unlock an object and do not report any updates */ 750b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 76a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid object_unlock_exclusive(IObject *this) 77a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 78fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 79fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 80fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(NULL != this->mFile); 81fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(0 != this->mLine); 82fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 83fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mFile = NULL; 84fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mLine = 0; 85fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 86a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 87a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 88a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 89a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 90a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 910b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 920b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Exclusively unlock an object and report updates to the specified bit-mask of attributes */ 930b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 94e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid object_unlock_exclusive_attributes(IObject *this, unsigned attributes) 95e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten{ 96fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten 97fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 98fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 99fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(NULL != this->mFile); 100fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(0 != this->mLine); 101fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 102fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten 103e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten int ok; 104e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten SLuint32 objectID = IObjectToObjectID(this); 105e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten CAudioPlayer *ap; 1064b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1074b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // FIXME The endless if statements are getting ugly, should use bit search 1084b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 109e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // Android likes to see certain updates synchronously 1103c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 111e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes & ATTR_GAIN) { 112e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten switch (objectID) { 113e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten case SL_OBJECTID_AUDIOPLAYER: 114e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten attributes &= ~ATTR_GAIN; // no need to process asynchronously also 115e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten ap = (CAudioPlayer *) this; 116e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#ifdef ANDROID 117d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_volumeUpdate(ap); 118e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 119e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten audioPlayerGainUpdate(ap); 120e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#endif 121e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten break; 122e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten case SL_OBJECTID_OUTPUTMIX: 123e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // FIXME update gains on all players attached to this outputmix 1240b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("[ FIXME: gain update on an SL_OBJECTID_OUTPUTMIX to be implemented ]"); 1253c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1263c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi case SL_OBJECTID_MIDIPLAYER: 1277a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // MIDI 1280b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("[ FIXME: gain update on an SL_OBJECTID_MIDIPLAYER to be implemented ]"); 129e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten break; 130e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten default: 131e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten break; 132e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 133e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 1343c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 1353c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (attributes & ATTR_POSITION) { 1363c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi switch (objectID) { 1373c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi case SL_OBJECTID_AUDIOPLAYER: 1383c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi ap = (CAudioPlayer *) this; 1393c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#ifdef ANDROID 1404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attributes &= ~ATTR_POSITION; // no need to process asynchronously also 141d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_seek(ap, ap->mSeek.mPos); 1423c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#else 1434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten //audioPlayerTransportUpdate(ap); 1443c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#endif 1453c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1463c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi case SL_OBJECTID_MIDIPLAYER: 1477a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // MIDI 1480b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("[ FIXME: position update on an SL_OBJECTID_MIDIPLAYER to be implemented ]"); 1493c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1503c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi default: 1513c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1523c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 1533c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 1543c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 155e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes & ATTR_TRANSPORT) { 156e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 1574b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef ANDROID 158e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten attributes &= ~ATTR_TRANSPORT; // no need to process asynchronously also 159e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten ap = (CAudioPlayer *) this; 160e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // FIXME should only call when state changes 161d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_setPlayState(ap); 162e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // FIXME ditto, but for either eventflags or marker position 163d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_useEventMask(ap); 164e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 1654b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten //audioPlayerTransportUpdate(ap); 166e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#endif 167e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 168e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 1694b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1704b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // ( buffer queue count is non-empty and play state == PLAYING ) became true 1714b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (attributes & ATTR_ENQUEUE) { 1724b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 1734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attributes &= ~ATTR_ENQUEUE; 1744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten ap = (CAudioPlayer *) this; 1754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (SL_PLAYSTATE_PLAYING == ap->mPlay.mState) { 176b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi#ifdef ANDROID 177a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi android_audioPlayer_bufferQueueRefilled(ap); 178b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi#endif 1794b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1814b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1824b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 183e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes) { 184e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten unsigned oldAttributesMask = this->mAttributesMask; 185e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten this->mAttributesMask = oldAttributesMask | attributes; 186e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (oldAttributesMask) 187e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten attributes = ATTR_NONE; 188e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 189fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 190fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 191fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mFile = NULL; 192fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mLine = 0; 193fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 194e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 195e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten assert(0 == ok); 196e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes) { // first update to this interface since previous sync 197e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten IEngine *thisEngine = this->mEngine; 198e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten interface_lock_exclusive(thisEngine); 199e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten thisEngine->mChangedMask |= 1 << (this->mInstanceID - 1); 200e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten interface_unlock_exclusive(thisEngine); 201e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 202e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten} 203e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 2040b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2050b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Wait on the condition variable associated with the object; see pthread_cond_wait */ 2060b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2074f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#ifdef USE_DEBUG 2084f064c143ef2b26347130a49788116b5d2e1252aGlenn Kastenvoid object_cond_wait_(IObject *this, const char *file, int line) 2094f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten{ 2104f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // note that this will unlock the mutex, so we have to clear the owner 2114f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 2124f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(NULL != this->mFile); 2134f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(0 != this->mLine); 2144f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 2154f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mFile = NULL; 2164f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mLine = 0; 2174f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // alas we don't know the new owner's identity 2184f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten int ok; 2194f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten ok = pthread_cond_wait(&this->mCond, &this->mMutex); 2204f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(0 == ok); 2214f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // restore my ownership 2224f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mOwner = pthread_self(); 2234f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mFile = file; 2244f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mLine = line; 2254f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten} 2264f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#else 227a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid object_cond_wait(IObject *this) 228a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 229a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 230a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_cond_wait(&this->mCond, &this->mMutex); 231a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 232a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 2334f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#endif 234a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 2350b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2360b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Signal the condition variable associated with the object; see pthread_cond_signal */ 2370b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 238a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid object_cond_signal(IObject *this) 239a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 240a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 241a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_cond_signal(&this->mCond); 242a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 243a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 244a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten 2450b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2460b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Broadcast the condition variable associated with the object; see pthread_cond_broadcast */ 2470b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 248a438eb1cf1ae602afab00336528dd230bd929206Glenn Kastenvoid object_cond_broadcast(IObject *this) 249a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten{ 250a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten int ok; 251a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten ok = pthread_cond_broadcast(&this->mCond); 252a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten assert(0 == ok); 253a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten} 254