locks.c revision 4597a7427b697df31d0bbf4c2040806d0c27b6e0
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 this->mOwner = pthread_self(); 59fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mFile = file; 60fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten this->mLine = line; 61fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten} 62fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#else 634f064c143ef2b26347130a49788116b5d2e1252aGlenn Kastenvoid object_lock_exclusive(IObject *this) 64a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 65a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 66a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_mutex_lock(&this->mMutex); 67a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 68a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 69fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 70a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 720b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Exclusively unlock an object and do not report any updates */ 730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 74fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 754597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenvoid object_unlock_exclusive_(IObject *this, const char *file, int line) 764597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{ 77fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 78fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(NULL != this->mFile); 79fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(0 != this->mLine); 80fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 814597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten this->mFile = file; 824597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten this->mLine = line; 83a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 84a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 85a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 86a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 874597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#else 884597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenvoid object_unlock_exclusive(IObject *this) 894597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{ 904597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten int ok; 914597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 924597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten assert(0 == ok); 934597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten} 944597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif 95a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 970b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Exclusively unlock an object and report updates to the specified bit-mask of attributes */ 980b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 994597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#ifdef USE_DEBUG 1004597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kastenvoid object_unlock_exclusive_attributes_(IObject *this, unsigned attributes, 1014597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten const char *file, int line) 1024597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#else 103e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenvoid object_unlock_exclusive_attributes(IObject *this, unsigned attributes) 1044597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif 105e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten{ 106fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten 107fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 108fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 109fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(NULL != this->mFile); 110fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten assert(0 != this->mLine); 111fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 112fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten 113e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten int ok; 114e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten SLuint32 objectID = IObjectToObjectID(this); 115e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten CAudioPlayer *ap; 1164b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1174b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // FIXME The endless if statements are getting ugly, should use bit search 1184b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 119e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // Android likes to see certain updates synchronously 1203c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 121e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes & ATTR_GAIN) { 122e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten switch (objectID) { 123e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten case SL_OBJECTID_AUDIOPLAYER: 124e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten attributes &= ~ATTR_GAIN; // no need to process asynchronously also 125e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten ap = (CAudioPlayer *) this; 126e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#ifdef ANDROID 127d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_volumeUpdate(ap); 128e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 129e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten audioPlayerGainUpdate(ap); 130e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#endif 131e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten break; 132e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten case SL_OBJECTID_OUTPUTMIX: 133e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // FIXME update gains on all players attached to this outputmix 1340b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("[ FIXME: gain update on an SL_OBJECTID_OUTPUTMIX to be implemented ]"); 1353c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1363c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi case SL_OBJECTID_MIDIPLAYER: 1377a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // MIDI 1380b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("[ FIXME: gain update on an SL_OBJECTID_MIDIPLAYER to be implemented ]"); 139e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten break; 140e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten default: 141e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten break; 142e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 143e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 1443c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 1453c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi if (attributes & ATTR_POSITION) { 1463c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi switch (objectID) { 1473c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi case SL_OBJECTID_AUDIOPLAYER: 1483c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi ap = (CAudioPlayer *) this; 1493c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#ifdef ANDROID 1504b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attributes &= ~ATTR_POSITION; // no need to process asynchronously also 151d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_seek(ap, ap->mSeek.mPos); 1523c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#else 1534b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten //audioPlayerTransportUpdate(ap); 1543c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi#endif 1553c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1563c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi case SL_OBJECTID_MIDIPLAYER: 1577a79f519d89eb0e1a5b3f4005484b16d6854d7e2Glenn Kasten // MIDI 1580b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten SL_LOGE("[ FIXME: position update on an SL_OBJECTID_MIDIPLAYER to be implemented ]"); 1593c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1603c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi default: 1613c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi break; 1623c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 1633c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 1643c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 165e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes & ATTR_TRANSPORT) { 166e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 1674b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef ANDROID 168e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten attributes &= ~ATTR_TRANSPORT; // no need to process asynchronously also 169e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten ap = (CAudioPlayer *) this; 170e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // FIXME should only call when state changes 171d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_setPlayState(ap); 172e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // FIXME ditto, but for either eventflags or marker position 173d739e18bea1deaf7c487f99a512c0ae7649615c2Jean-Michel Trivi android_audioPlayer_useEventMask(ap); 174e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 1754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten //audioPlayerTransportUpdate(ap); 176e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#endif 177e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 178e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 1794b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // ( buffer queue count is non-empty and play state == PLAYING ) became true 1814b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (attributes & ATTR_ENQUEUE) { 1824b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 1834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten attributes &= ~ATTR_ENQUEUE; 1844b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten ap = (CAudioPlayer *) this; 1854b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if (SL_PLAYSTATE_PLAYING == ap->mPlay.mState) { 186b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi#ifdef ANDROID 187a05622c974763d8ca038f3d39743c926309ab2c2Jean-Michel Trivi android_audioPlayer_bufferQueueRefilled(ap); 188b44084fdb096a2662085af0199b69ccb0dce5c30Jean-Michel Trivi#endif 1894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1904b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 193e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes) { 194e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten unsigned oldAttributesMask = this->mAttributesMask; 195e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten this->mAttributesMask = oldAttributesMask | attributes; 196e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (oldAttributesMask) 197e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten attributes = ATTR_NONE; 198e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 199fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 200fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 2014597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten this->mFile = file; 2024597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten this->mLine = line; 203fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 204e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 205e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten assert(0 == ok); 206e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten if (attributes) { // first update to this interface since previous sync 207e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten IEngine *thisEngine = this->mEngine; 208e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten interface_lock_exclusive(thisEngine); 209e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten thisEngine->mChangedMask |= 1 << (this->mInstanceID - 1); 210e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten interface_unlock_exclusive(thisEngine); 211e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 212e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten} 213e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 2140b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2150b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Wait on the condition variable associated with the object; see pthread_cond_wait */ 2160b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2174f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#ifdef USE_DEBUG 2184f064c143ef2b26347130a49788116b5d2e1252aGlenn Kastenvoid object_cond_wait_(IObject *this, const char *file, int line) 2194f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten{ 2204f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // note that this will unlock the mutex, so we have to clear the owner 2214f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 2224f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(NULL != this->mFile); 2234f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(0 != this->mLine); 2244f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 2254597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten this->mFile = file; 2264597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten this->mLine = line; 2274f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // alas we don't know the new owner's identity 2284f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten int ok; 2294f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten ok = pthread_cond_wait(&this->mCond, &this->mMutex); 2304f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(0 == ok); 2314f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // restore my ownership 2324f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mOwner = pthread_self(); 2334f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mFile = file; 2344f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten this->mLine = line; 2354f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten} 2364f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#else 237a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid object_cond_wait(IObject *this) 238a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 239a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 240a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_cond_wait(&this->mCond, &this->mMutex); 241a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 242a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 2434f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#endif 244a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 2450b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2460b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Signal the condition variable associated with the object; see pthread_cond_signal */ 2470b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 248a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid object_cond_signal(IObject *this) 249a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 250a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 251a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten ok = pthread_cond_signal(&this->mCond); 252a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 253a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 254a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten 2550b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2560b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten/* Broadcast the condition variable associated with the object; see pthread_cond_broadcast */ 2570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 258a438eb1cf1ae602afab00336528dd230bd929206Glenn Kastenvoid object_cond_broadcast(IObject *this) 259a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten{ 260a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten int ok; 261a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten ok = pthread_cond_broadcast(&this->mCond); 262a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten assert(0 == ok); 263a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten} 264