182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten/* 282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * 482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * you may not use this file except in compliance with the License. 682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * You may obtain a copy of the License at 782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * 882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 982b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * 1082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * Unless required by applicable law or agreed to in writing, software 1182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 1282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * See the License for the specific language governing permissions and 1482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten * limitations under the License. 1582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten */ 1682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 1782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten#include "sles_allinclusive.h" 1882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 19158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 204f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten/** \brief Exclusively lock an object */ 21158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 223190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#ifdef USE_DEBUG 233190a0da044e122c1c617e30d1d364701fb27110Glenn Kastenvoid object_lock_exclusive_(IObject *this, const char *file, int line) 243190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten{ 253190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten int ok; 263190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten ok = pthread_mutex_trylock(&this->mMutex); 273190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten if (0 != ok) { 2807c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten // pthread_mutex_timedlock_np is not available, but wait up to 100 ms 2907c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten static const useconds_t backoffs[] = {1, 10000, 20000, 30000, 40000}; 3007c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten unsigned i = 0; 3107c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten for (;;) { 3207c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten usleep(backoffs[i]); 3307c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten ok = pthread_mutex_trylock(&this->mMutex); 3407c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten if (0 == ok) 3507c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten break; 3607c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten if (++i >= (sizeof(backoffs) / sizeof(backoffs[0]))) { 37227b8b5fe36d5385bbb23d63198bc8e72bfda5d3Glenn Kasten SL_LOGW("%s:%d: object %p was locked by %p at %s:%d\n", 3807c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten file, line, this, *(void **)&this->mOwner, this->mFile, this->mLine); 3907c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten // attempt one more time; maybe this time we will be successful 4007c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten ok = pthread_mutex_lock(&this->mMutex); 4107c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten assert(0 == ok); 4207c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten break; 4307c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten } 4407c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten } 453190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten } 463190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten pthread_t zero; 473190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten memset(&zero, 0, sizeof(pthread_t)); 4807c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten if (0 != memcmp(&zero, &this->mOwner, sizeof(pthread_t))) { 4907c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten if (pthread_equal(pthread_self(), this->mOwner)) { 5007c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten SL_LOGE("%s:%d: object %p was recursively locked by %p at %s:%d\n", 5107c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten file, line, this, *(void **)&this->mOwner, this->mFile, this->mLine); 5207c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten } else { 5307c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten SL_LOGE("%s:%d: object %p was left unlocked in unexpected state by %p at %s:%d\n", 5407c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten file, line, this, *(void **)&this->mOwner, this->mFile, this->mLine); 5507c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten } 5607c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten assert(false); 5707c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten } 583190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten this->mOwner = pthread_self(); 593190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten this->mFile = file; 603190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten this->mLine = line; 613190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten} 623190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#else 6307c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kastenvoid object_lock_exclusive(IObject *this) 6482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 6582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten int ok; 6682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten ok = pthread_mutex_lock(&this->mMutex); 6782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten assert(0 == ok); 6882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 693190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#endif 7082b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 71158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 724f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten/** \brief Exclusively unlock an object and do not report any updates */ 73158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 743190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#ifdef USE_DEBUG 75974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kastenvoid object_unlock_exclusive_(IObject *this, const char *file, int line) 76974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten{ 773190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 783190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten assert(NULL != this->mFile); 793190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten assert(0 != this->mLine); 803190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 81974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten this->mFile = file; 82974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten this->mLine = line; 8382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten int ok; 8482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 8582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten assert(0 == ok); 8682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 87974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten#else 88974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kastenvoid object_unlock_exclusive(IObject *this) 89974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten{ 90974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten int ok; 91974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 92974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten assert(0 == ok); 93974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten} 94974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten#endif 9582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 96158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 974f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten/** \brief Exclusively unlock an object and report updates to the specified bit-mask of 984f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten * attributes 994f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten */ 100158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 101974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten#ifdef USE_DEBUG 102974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kastenvoid object_unlock_exclusive_attributes_(IObject *this, unsigned attributes, 103974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten const char *file, int line) 104974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten#else 10515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kastenvoid object_unlock_exclusive_attributes(IObject *this, unsigned attributes) 106974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten#endif 10715f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten{ 1083190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten 1093190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#ifdef USE_DEBUG 1103190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 1113190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten assert(NULL != this->mFile); 1123190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten assert(0 != this->mLine); 1133190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#endif 1143190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten 11515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten int ok; 11615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten SLuint32 objectID = IObjectToObjectID(this); 11715f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten CAudioPlayer *ap; 11823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 11923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten // FIXME The endless if statements are getting ugly, should use bit search 12023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 12115f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten // Android likes to see certain updates synchronously 122d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi 12315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten if (attributes & ATTR_GAIN) { 12415f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten switch (objectID) { 12515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten case SL_OBJECTID_AUDIOPLAYER: 12615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten attributes &= ~ATTR_GAIN; // no need to process asynchronously also 12715f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten ap = (CAudioPlayer *) this; 12815f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten#ifdef ANDROID 129f66a508b11e327670a6bf5a8cf9c106f215e3b39Jean-Michel Trivi android_audioPlayer_volumeUpdate(ap); 13015f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten#else 13115f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten audioPlayerGainUpdate(ap); 13215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten#endif 13315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten break; 13415f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten case SL_OBJECTID_OUTPUTMIX: 13515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten // FIXME update gains on all players attached to this outputmix 13603716fc64636a68ba59881508e80550b948f0f40Glenn Kasten SL_LOGD("[ FIXME: gain update on an SL_OBJECTID_OUTPUTMIX to be implemented ]"); 137d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi break; 138d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi case SL_OBJECTID_MIDIPLAYER: 139f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten // MIDI 14003716fc64636a68ba59881508e80550b948f0f40Glenn Kasten SL_LOGD("[ FIXME: gain update on an SL_OBJECTID_MIDIPLAYER to be implemented ]"); 14115f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten break; 14215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten default: 14315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten break; 14415f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten } 14515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten } 146d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi 147d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi if (attributes & ATTR_POSITION) { 148d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi switch (objectID) { 149d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi case SL_OBJECTID_AUDIOPLAYER: 150d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi#ifdef ANDROID 151bf53474b725519ebeab2997e975375d896ff91beGlenn Kasten ap = (CAudioPlayer *) this; 15223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten attributes &= ~ATTR_POSITION; // no need to process asynchronously also 153f66a508b11e327670a6bf5a8cf9c106f215e3b39Jean-Michel Trivi android_audioPlayer_seek(ap, ap->mSeek.mPos); 154d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi#else 15523c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten //audioPlayerTransportUpdate(ap); 156d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi#endif 157d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi break; 158d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi case SL_OBJECTID_MIDIPLAYER: 159f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten // MIDI 16003716fc64636a68ba59881508e80550b948f0f40Glenn Kasten SL_LOGD("[ FIXME: position update on an SL_OBJECTID_MIDIPLAYER to be implemented ]"); 161d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi break; 162d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi default: 163d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi break; 164d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi } 165d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi } 166d0222eec2f5ae565ab930fc1364950ab4530e1e8Jean-Michel Trivi 16715f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten if (attributes & ATTR_TRANSPORT) { 16815f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 16923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#ifdef ANDROID 17015f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten attributes &= ~ATTR_TRANSPORT; // no need to process asynchronously also 17115f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten ap = (CAudioPlayer *) this; 17215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten // FIXME should only call when state changes 1738c5a381a265210f069a370565f10ce31bf886346Jean-Michel Trivi android_audioPlayer_setPlayState(ap, false /*lockAP*/); 17415f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten // FIXME ditto, but for either eventflags or marker position 175f66a508b11e327670a6bf5a8cf9c106f215e3b39Jean-Michel Trivi android_audioPlayer_useEventMask(ap); 17615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten#else 17723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten //audioPlayerTransportUpdate(ap); 17815f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten#endif 17991ebb75cfa76cc573ced127e59cad7dd950ce08aJean-Michel Trivi } else if (SL_OBJECTID_AUDIORECORDER == objectID) { 18091ebb75cfa76cc573ced127e59cad7dd950ce08aJean-Michel Trivi#ifdef ANDROID 18191ebb75cfa76cc573ced127e59cad7dd950ce08aJean-Michel Trivi attributes &= ~ATTR_TRANSPORT; // no need to process asynchronously also 18291ebb75cfa76cc573ced127e59cad7dd950ce08aJean-Michel Trivi CAudioRecorder* ar = (CAudioRecorder *) this; 18391ebb75cfa76cc573ced127e59cad7dd950ce08aJean-Michel Trivi android_audioRecorder_useEventMask(ar); 18491ebb75cfa76cc573ced127e59cad7dd950ce08aJean-Michel Trivi#endif 18515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten } 18615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten } 18723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 18823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten // ( buffer queue count is non-empty and play state == PLAYING ) became true 18923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten if (attributes & ATTR_ENQUEUE) { 19023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 19123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten attributes &= ~ATTR_ENQUEUE; 19223c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten ap = (CAudioPlayer *) this; 19323c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten if (SL_PLAYSTATE_PLAYING == ap->mPlay.mState) { 194b746b8006289cf3baed344fc8d827c423963f553Jean-Michel Trivi#ifdef ANDROID 195614d5407d3fac1dae8975722f25e671642041282Jean-Michel Trivi android_audioPlayer_bufferQueue_onRefilled(ap); 196b746b8006289cf3baed344fc8d827c423963f553Jean-Michel Trivi#endif 19723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten } 19823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten } 19923c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten } 20023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten 20115f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten if (attributes) { 20215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten unsigned oldAttributesMask = this->mAttributesMask; 20315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten this->mAttributesMask = oldAttributesMask | attributes; 20415f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten if (oldAttributesMask) 20515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten attributes = ATTR_NONE; 20615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten } 2073190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#ifdef USE_DEBUG 2083190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 209974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten this->mFile = file; 210974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten this->mLine = line; 2113190a0da044e122c1c617e30d1d364701fb27110Glenn Kasten#endif 21215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten ok = pthread_mutex_unlock(&this->mMutex); 21315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten assert(0 == ok); 21431df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten // first update to this interface since previous sync 21531df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten if (attributes) { 21631df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten unsigned id = this->mInstanceID; 21731df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten if (0 != id) { 21831df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten --id; 21931df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten assert(MAX_INSTANCE > id); 22031df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten IEngine *thisEngine = this->mEngine; 22131df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten interface_lock_exclusive(thisEngine); 22231df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten thisEngine->mChangedMask |= 1 << id; 22331df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten interface_unlock_exclusive(thisEngine); 22431df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten } 22515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten } 22615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten} 22715f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten 228158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 2294f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten/** \brief Wait on the condition variable associated with the object; see pthread_cond_wait */ 230158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 23107c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten#ifdef USE_DEBUG 23207c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kastenvoid object_cond_wait_(IObject *this, const char *file, int line) 23307c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten{ 23407c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten // note that this will unlock the mutex, so we have to clear the owner 23507c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten assert(pthread_equal(pthread_self(), this->mOwner)); 23607c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten assert(NULL != this->mFile); 23707c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten assert(0 != this->mLine); 23807c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten memset(&this->mOwner, 0, sizeof(pthread_t)); 239974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten this->mFile = file; 240974aacf14bfe6869b7d0cda3abcaef46af335487Glenn Kasten this->mLine = line; 24107c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten // alas we don't know the new owner's identity 24207c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten int ok; 24307c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten ok = pthread_cond_wait(&this->mCond, &this->mMutex); 24407c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten assert(0 == ok); 24507c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten // restore my ownership 24607c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten this->mOwner = pthread_self(); 24707c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten this->mFile = file; 24807c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten this->mLine = line; 24907c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten} 25007c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten#else 25182b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenvoid object_cond_wait(IObject *this) 25282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 25382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten int ok; 25482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten ok = pthread_cond_wait(&this->mCond, &this->mMutex); 25582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten assert(0 == ok); 25682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 25707c35e6e57ff8945c4dd836be4486a62316ac64bGlenn Kasten#endif 25882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten 259158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 2604f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten/** \brief Signal the condition variable associated with the object; see pthread_cond_signal */ 261158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 26282b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kastenvoid object_cond_signal(IObject *this) 26382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten{ 26482b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten int ok; 26582b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten ok = pthread_cond_signal(&this->mCond); 26682b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten assert(0 == ok); 26782b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten} 268c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kasten 269158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 2704f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten/** \brief Broadcast the condition variable associated with the object; 2714f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten * see pthread_cond_broadcast 2724f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten */ 273158dbd1a71a890d29490198c8e5019081ac94ac3Glenn Kasten 274c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kastenvoid object_cond_broadcast(IObject *this) 275c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kasten{ 276c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kasten int ok; 277c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kasten ok = pthread_cond_broadcast(&this->mCond); 278c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kasten assert(0 == ok); 279c37c934e00a96afe18aaadd9f9a1863c721bf8eaGlenn Kasten} 280