C++ (Qt)struct CPageHead { CPageData * AcquireRead( void ); void * ReleaseRead( void ) { mMutex.unlock(); } CPageData * mData; atomic <UInt32> mAccessCount; spin_rw_mutex mMutex; static atomic <UInt32> mAccessTotal; static spin_mutex mLoadMutex;}; CPageData * CPageHead::AcquireRead( void ){ mMutex.lock_read(); // здесь mData может быть загружена или нет, но не может быть выгружена if (!mData) { // не загружена spin_mutex::scoped_lock theLock(mLoadMutex); // берем лок if (!mData) { // др. нитка успела подгрузить?// UInt32_64 * dummy = (UInt32_64 *) &mMutex; // неверно! (предыдущий вариант) atomic <UInt32_64> * dummy = (atomic <UInt32_64> *) &mMutex; *dummy += WRITE_PENDING; // блокируем доступ по чтению во время LoadPage LoadPage(); // грузим апельсины бочками *dummy -= WRITE_PENDING; // mData готово, можно читать } } // обновляем статистику mAccessCount = ++mAccessTotal; return mData;}
C++ (Qt)*dummy |= WRITE_PENDING;
C++ (Qt)Data *acquire (){ m_mutex.lock_read (); if (!m_data) { scoped_lock sl (m_load_mutex); if (!m_data) { Data *tmp = LoadPage (); //first load m_data = tmp; //tmp is ready, assign m_data to it } } return m_data;}