コード例 #1
0
void
ArchivePublisher::enterRetryingState()
{
    assert(mState == PUBLISH_BEGIN || mState == PUBLISH_SENDING ||
           mState == PUBLISH_COMMITTING);
    mState = PUBLISH_RETRYING;
    mRetryTimer.expires_from_now(std::chrono::seconds(2));
    std::weak_ptr<ArchivePublisher> weak(shared_from_this());
    mRetryTimer.async_wait(
        [weak](asio::error_code const& ec)
        {
            auto self = weak.lock();
            if (!self)
            {
                return;
            }
            if (self->mRetryCount++ > kRetryLimit)
            {
                CLOG(WARNING, "History")
                    << "Retry count " << kRetryLimit
                    << " exceeded, abandonning  publish-attempt on archive '"
                    << self->mArchive->getName() << "'";
                self->enterEndState();
            }
            else
            {
                CLOG(INFO, "History") << "Retrying publish to archive '"
                                      << self->mArchive->getName() << "'";
                self->enterBeginState();
            }
        });
}
コード例 #2
0
void
ArchivePublisher::enterCommittingState()
{
    assert(mState == PUBLISH_SENDING);
    mState = PUBLISH_COMMITTING;
    std::weak_ptr<ArchivePublisher> weak(shared_from_this());
    mArchive->putState(
        mApp, mSnap->mLocalState, [weak](asio::error_code const& ec)
        {
            auto self = weak.lock();
            if (!self)
            {
                return;
            }
            if (ec)
            {
                CLOG(WARNING, "History")
                    << "Publisher failed to update state in history archive '"
                    << self->mArchive->getName() << "', restarting publish";
                self->enterRetryingState();
            }
            else
            {
                self->enterEndState();
            }
        });
}
コード例 #3
0
ファイル: vaapidisplay.cpp プロジェクト: TangXinT/libyami
DisplayPtr DisplayCache::createDisplay(const NativeDisplay& nativeDisplay)
{
    NativeDisplayPtr nativeDisplayObj;
    VADisplay vaDisplay = NULL;
    DisplayPtr vaapiDisplay;
    YamiMediaCodec::AutoLock locker(m_lock);

    m_cache.remove_if(expired);

    //lockup first
    list<weak_ptr<VaapiDisplay> >::iterator it;
    for (it = m_cache.begin(); it != m_cache.end(); ++it) {
        vaapiDisplay = (*it).lock();
        if (vaapiDisplay->isCompatible(nativeDisplay)) {
            return vaapiDisplay;
        }
    }
    vaapiDisplay.reset();

    //crate new one
    DEBUG("nativeDisplay: (type : %d), (handle : 0x%x)", nativeDisplay.type, nativeDisplay.handle);

    switch (nativeDisplay.type) {
    case NATIVE_DISPLAY_AUTO:
#if __ENABLE_X11__
    case NATIVE_DISPLAY_X11:
        nativeDisplayObj.reset (new NativeDisplayX11());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplay((Display*)(nativeDisplayObj->nativeHandle()));
        if (vaDisplay)
            INFO("use vaapi x11 backend");
        if(vaDisplay || nativeDisplay.type == NATIVE_DISPLAY_X11)
            break;
        INFO("try to init va with x11 display (%p) but failed", (Display*)(nativeDisplayObj->nativeHandle()));
        // NATIVE_DISPLAY_AUTO continue, no break
#endif
    case NATIVE_DISPLAY_DRM:
        nativeDisplayObj.reset (new NativeDisplayDrm());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplayDRM(nativeDisplayObj->nativeHandle());
        INFO("use vaapi drm backend");
        break;
    default:
        break;
    }

    if (vaDisplay == NULL) {
        ERROR("vaGetDisplay failed.");
        return vaapiDisplay;
    }

    if (vaInit(vaDisplay))
        vaapiDisplay.reset(new VaapiDisplay(nativeDisplayObj, vaDisplay));

    if (vaapiDisplay) {
        weak_ptr<VaapiDisplay> weak(vaapiDisplay);
        m_cache.push_back(weak);
    }
    return vaapiDisplay;
}
コード例 #4
0
void
ArchivePublisher::enterBeginState()
{
    assert(mState == PUBLISH_RETRYING);
    mState = PUBLISH_BEGIN;
    std::weak_ptr<ArchivePublisher> weak(shared_from_this());
    mArchive->getMostRecentState(
        mApp, [weak](asio::error_code const& ec, HistoryArchiveState const& has)
        {
            auto self = weak.lock();
            if (!self)
            {
                return;
            }
            if (ec)
            {
                CLOG(WARNING, "History") << "Publisher failed to retrieve "
                                            "state from history archive '"
                                         << self->mArchive->getName()
                                         << "', restarting publish";
                self->enterRetryingState();
            }
            else
            {
                self->enterObservedState(has);
            }
        });
}
コード例 #5
0
void JSWeakValue::setString(JSString* string, WeakHandleOwner& owner, void* context)
{
    ASSERT(!isSet());
    ASSERT(!m_value.string);
    m_tag = WeakTypeTag::String;
    Weak<JSString> weak(string, &owner, context);
    m_value.string.swap(weak);
}
コード例 #6
0
void JSWeakValue::setObject(JSObject* object, WeakHandleOwner& owner, void* context)
{
    ASSERT(!isSet());
    ASSERT(!m_value.object);
    m_tag = WeakTypeTag::Object;
    Weak<JSObject> weak(object, &owner, context);
    m_value.object.swap(weak);
}
コード例 #7
0
ファイル: FontCacheFreeType.cpp プロジェクト: nickooms/webkit
static AliasStrength strengthOfFirstAlias(const FcPattern& original)
{
    // Ideally there would exist a call like
    // FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak);
    //
    // However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit.
    // Currently, the only reliable way of finding the weak bit is by its effect on matching.
    // The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values.
    // A element with the weak bit is scored after FC_LANG, without the weak bit is scored before.
    // Note that the weak bit is stored on the element, not on the value it holds.
    FcValue value;
    FcResult result = FcPatternGet(&original, FC_FAMILY, 0, &value);
    if (result != FcResultMatch)
        return AliasStrength::Done;

    RefPtr<FcPattern> pattern = adoptRef(FcPatternDuplicate(&original));
    FcBool hasMultipleFamilies = true;
    while (hasMultipleFamilies)
        hasMultipleFamilies = FcPatternRemove(pattern.get(), FC_FAMILY, 1);

    // Create a font set with two patterns.
    // 1. the same FC_FAMILY as pattern and a lang object with only 'nomatchlang'.
    // 2. a different FC_FAMILY from pattern and a lang object with only 'matchlang'.
    FcUniquePtr<FcFontSet> fontSet(FcFontSetCreate());

    FcUniquePtr<FcLangSet> strongLangSet(FcLangSetCreate());
    FcLangSetAdd(strongLangSet.get(), reinterpret_cast<const FcChar8*>("nomatchlang"));
    RefPtr<FcPattern> strong = adoptRef(FcPatternDuplicate(pattern.get()));
    FcPatternAddLangSet(strong.get(), FC_LANG, strongLangSet.get());

    FcUniquePtr<FcLangSet> weakLangSet(FcLangSetCreate());
    FcLangSetAdd(weakLangSet.get(), reinterpret_cast<const FcChar8*>("matchlang"));
    RefPtr<FcPattern> weak(FcPatternCreate());
    FcPatternAddString(weak.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>("nomatchstring"));
    FcPatternAddLangSet(weak.get(), FC_LANG, weakLangSet.get());

    FcFontSetAdd(fontSet.get(), strong.leakRef());
    FcFontSetAdd(fontSet.get(), weak.leakRef());

    // Add 'matchlang' to the copy of the pattern.
    FcPatternAddLangSet(pattern.get(), FC_LANG, weakLangSet.get());

    // Run a match against the copy of the pattern.
    // If the first element was weak, then we should match the pattern with 'matchlang'.
    // If the first element was strong, then we should match the pattern with 'nomatchlang'.

    // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
    // However, there appears to be no way to match/sort without it.
    RefPtr<FcConfig> config = adoptRef(FcConfigCreate());
    FcFontSet* fontSets[1] = { fontSet.get() };
    RefPtr<FcPattern> match = adoptRef(FcFontSetMatch(config.get(), fontSets, 1, pattern.get(), &result));

    FcLangSet* matchLangSet;
    FcPatternGetLangSet(match.get(), FC_LANG, 0, &matchLangSet);
    return FcLangEqual == FcLangSetHasLang(matchLangSet, reinterpret_cast<const FcChar8*>("matchlang"))
        ? AliasStrength::Weak : AliasStrength::Strong;
}
コード例 #8
0
int Thread::_threadLoop(void* user)
{
    Thread* const self = static_cast<Thread*>(user);
    sp<Thread> strong(self->mHoldSelf);
    wp<Thread> weak(strong);
    self->mHoldSelf.clear();

#if HAVE_ANDROID_OS
    // this is very useful for debugging with gdb
    self->mTid = gettid();
#endif

    bool first = true;

    do {
        bool result;
        if (first) {
            first = false;
            self->mStatus = self->readyToRun();
            result = (self->mStatus == NO_ERROR);

            if (result && !self->mExitPending) {
                // Binder threads (and maybe others) rely on threadLoop
                // running at least once after a successful ::readyToRun()
                // (unless, of course, the thread has already been asked to exit
                // at that point).
                // This is because threads are essentially used like this:
                //   (new ThreadSubclass())->run();
                // The caller therefore does not retain a strong reference to
                // the thread and the thread would simply disappear after the
                // successful ::readyToRun() call instead of entering the
                // threadLoop at least once.
                result = self->threadLoop();
            }
        } else {
            result = self->threadLoop();
        }

        if (result == false || self->mExitPending) {
            self->mExitPending = true;
            self->mLock.lock();
            self->mRunning = false;
            self->mThreadExitedCondition.broadcast();
			self->mThread = thread_id_t(-1); // thread id could be reused
            self->mLock.unlock();
            break;
        }
        
        // Release our strong reference, to let a chance to the thread
        // to die a peaceful death.
        strong.clear();
        // And immediately, re-acquire a strong reference for the next loop
        strong = weak.promote();
    } while(strong != 0);
    
    return 0;
}
コード例 #9
0
ファイル: Scene.cpp プロジェクト: mmetcalfe/comp3320-project
    void Scene::addModel(std::shared_ptr<Model> model) {
        models.push_back(model);

        for (auto light : model->lights) {
            light->dir = glm::normalize(light->dir);
            std::weak_ptr<Light> weak(light);
            lights.push_back(weak);
        }
    }
コード例 #10
0
ファイル: Server.cpp プロジェクト: Metabolix/PutkaRTS
void Connection::Server::run() {
	std::weak_ptr<Server> weak(shared_from_this());
	while (std::shared_ptr<Server> ptr = weak.lock()) {
		if (state == END) {
			return;
		}
		update();
		std::this_thread::sleep_for(std::chrono::milliseconds(5));
	}
}
コード例 #11
0
void InterfaceWindow::RenderWindowShadow( float _x, float _y, float _h, float _w, float _size, float _alpha )
{
    glShadeModel( GL_SMOOTH );
    
    Colour strong(0,0,0,_alpha*255);
    Colour weak(0,0,0,0);

    g_renderer->RectFill( _x, _y+_size, _size, _h-_size, strong, weak, weak, strong );
    g_renderer->RectFill( _x, _y+_h, _size, _size, strong, weak, weak, weak );
    g_renderer->RectFill( _x-_w+_size, _y+_h, _w-_size, _size, strong, strong, weak, weak );
}
コード例 #12
0
ファイル: Work.cpp プロジェクト: vogel/stellar-core
std::function<void(asio::error_code const& ec)>
Work::callComplete()
{
    std::weak_ptr<Work> weak(
        std::static_pointer_cast<Work>(shared_from_this()));
    return [weak](asio::error_code const& ec) {
        auto self = weak.lock();
        if (!self)
        {
            return;
        }
        self->complete(ec ? WORK_COMPLETE_FAILURE : WORK_COMPLETE_OK);
    };
}
コード例 #13
0
ファイル: Work.cpp プロジェクト: vogel/stellar-core
void
Work::scheduleRetry()
{
    if (mScheduled)
    {
        return;
    }

    if (getState() != WORK_FAILURE_RETRY)
    {
        std::string msg = fmt::format("retrying {} in state {}",
                                      getUniqueName(), stateName(getState()));
        CLOG(ERROR, "Work") << msg;
        throw std::runtime_error(msg);
    }

    if (!mRetryTimer)
    {
        mRetryTimer = std::make_unique<VirtualTimer>(mApp.getClock());
    }

    std::weak_ptr<Work> weak(
        std::static_pointer_cast<Work>(shared_from_this()));
    auto t = getRetryDelay();
    mRetryTimer->expires_from_now(t);
    CLOG(WARNING, "Work")
        << "Scheduling retry #" << (mRetries + 1) << "/" << mMaxRetries
        << " in " << std::chrono::duration_cast<std::chrono::seconds>(t).count()
        << " sec, for " << getUniqueName();
    mScheduled = true;
    mRetryTimer->async_wait(
        [weak]() {
            auto self = weak.lock();
            if (!self)
            {
                return;
            }
            self->mScheduled = false;
            self->mRetries++;
            self->reset();
            self->advance();
        },
        VirtualTimer::onFailureNoop);
}
コード例 #14
0
nsresult
nsListBoxBodyFrame::DoInternalPositionChangedSync(PRBool aUp, PRInt32 aDelta)
{
  nsWeakFrame weak(this);
  
  // Process all the pending position changes first
  nsTArray< nsRefPtr<nsPositionChangedEvent> > temp;
  temp.SwapElements(mPendingPositionChangeEvents);
  for (PRUint32 i = 0; i < temp.Length(); ++i) {
    temp[i]->Run();
    temp[i]->Revoke();
  }

  if (!weak.IsAlive()) {
    return NS_OK;
  }

  return DoInternalPositionChanged(aUp, aDelta);
}
コード例 #15
0
void stateful_protocol_strategy_wrapper::Parse(
	const wchar_t* pData, int charCount, ClientInfoPtr pClientInfo)
{
	purge_dead_clients();

	std::weak_ptr<ClientInfo> weak(pClientInfo);
	ProtocolStrategyPtr strategy;
	auto strategy_iter = strategies_.find(weak);

	if (strategy_iter == strategies_.end())
	{
		strategy = factory_();
		strategies_.insert(std::make_pair(weak, strategy));
	}
	else
	{
		strategy = strategy_iter->second;
	}

	strategy->Parse(pData, charCount, pClientInfo);
}
コード例 #16
0
ファイル: Work.cpp プロジェクト: graydon/stellar-core
void
Work::scheduleRun()
{
    if (mScheduled)
    {
        return;
    }

    std::weak_ptr<Work> weak(
        std::static_pointer_cast<Work>(shared_from_this()));
    CLOG(DEBUG, "Work") << "scheduling run of " << getUniqueName();
    mScheduled = true;
    mApp.postOnMainThreadWithDelay([weak]() {
        auto self = weak.lock();
        if (!self)
        {
            return;
        }
        self->mScheduled = false;
        self->run();
    });
}
コード例 #17
0
ファイル: Work.cpp プロジェクト: tzdybal/stellar-core
void
Work::scheduleComplete(CompleteResult result)
{
    if (mScheduled)
    {
        return;
    }

    std::weak_ptr<Work> weak(
        std::static_pointer_cast<Work>(shared_from_this()));
    CLOG(DEBUG, "Work") << "scheduling completion of " << getUniqueName();
    mScheduled = true;
    mApp.getClock().getIOService().post([weak, result]() {
        auto self = weak.lock();
        if (!self)
        {
            return;
        }
        self->mScheduled = false;
        self->complete(result);
    });
}
コード例 #18
0
nsresult
nsListBoxBodyFrame::ScrollToIndex(PRInt32 aRowIndex)
{
  if (( aRowIndex < 0 ) || (mRowHeight == 0))
    return NS_OK;
    
  PRInt32 newIndex = aRowIndex;
  PRInt32 delta = mCurrentIndex > newIndex ? mCurrentIndex - newIndex : newIndex - mCurrentIndex;
  bool up = newIndex < mCurrentIndex;

  // Check to be sure we're not scrolling off the bottom of the tree
  PRInt32 lastPageTopRow = GetRowCount() - (GetAvailableHeight() / mRowHeight);
  if (lastPageTopRow < 0)
    lastPageTopRow = 0;

  if (aRowIndex > lastPageTopRow)
    return NS_OK;

  mCurrentIndex = newIndex;

  nsWeakFrame weak(this);

  // Since we're going to flush anyway, we need to not do this off an event
  DoInternalPositionChangedSync(up, delta);

  if (!weak.IsAlive()) {
    return NS_OK;
  }

  // This change has to happen immediately.
  // Flush any pending reflow commands.
  // XXXbz why, exactly?
  mContent->GetDocument()->FlushPendingNotifications(Flush_Layout);

  return NS_OK;
}
コード例 #19
0
ファイル: Heap.cpp プロジェクト: sysrqb/chromium-src
void Heap::addFinalizer(JSCell* cell, Finalizer finalizer)
{
    Weak<JSCell> weak(*globalData(), cell, &m_finalizerOwner, reinterpret_cast<void*>(finalizer));
    weak.leakHandle(); // Balanced by FinalizerOwner::finalize().
}
コード例 #20
0
void
ArchivePublisher::enterSendingState()
{
    assert(mState == PUBLISH_OBSERVED || mState == PUBLISH_SENDING);
    mState = PUBLISH_SENDING;

    FilePublishState minimumState = FILE_PUBLISH_UPLOADED;
    auto& hm = mApp.getHistoryManager();
    std::weak_ptr<ArchivePublisher> weak(shared_from_this());

    for (auto& pair : mFileInfos)
    {
        auto fi = pair.second;
        std::string name = fi->baseName_nogz();

        switch (fi->getState())
        {
        case FILE_PUBLISH_FAILED:
            break;

        case FILE_PUBLISH_NEEDED:
            fi->setState(FILE_PUBLISH_COMPRESSING);
            CLOG(DEBUG, "History") << "Compressing " << name;
            hm.compress(fi->localPath_nogz(),
                        [weak, name](asio::error_code const& ec)
                        {
                            auto self = weak.lock();
                            if (!self)
                            {
                                return;
                            }
                            self->fileStateChange(ec, name,
                                                  FILE_PUBLISH_COMPRESSED);
                        },
                        true);
            break;

        case FILE_PUBLISH_COMPRESSING:
            break;

        case FILE_PUBLISH_COMPRESSED:
            fi->setState(FILE_PUBLISH_MAKING_DIR);
            CLOG(DEBUG, "History") << "Making remote directory "
                                   << fi->remoteDir();
            hm.mkdir(mArchive, fi->remoteDir(),
                     [weak, name](asio::error_code const& ec)
                     {
                         auto self = weak.lock();
                         if (!self)
                         {
                             return;
                         }
                         self->fileStateChange(ec, name, FILE_PUBLISH_MADE_DIR);
                     });
            break;

        case FILE_PUBLISH_MAKING_DIR:
            break;

        case FILE_PUBLISH_MADE_DIR:
            fi->setState(FILE_PUBLISH_UPLOADING);
            CLOG(INFO, "History") << "Publishing " << name;
            hm.putFile(mArchive, fi->localPath_gz(), fi->remoteName(),
                       [weak, name](asio::error_code const& ec)
                       {
                         auto self = weak.lock();
                         if (!self)
                         {
                             return;
                         }
                         self->fileStateChange(ec, name,
                                               FILE_PUBLISH_UPLOADED);
                       });
            break;

        case FILE_PUBLISH_UPLOADING:
            break;

        case FILE_PUBLISH_UPLOADED:
            std::remove(fi->localPath_gz().c_str());
            break;
        }

        minimumState = std::min(fi->getState(), minimumState);
    }

    if (minimumState == FILE_PUBLISH_FAILED)
    {
        CLOG(WARNING, "History") << "Some file-puts failed, retrying";
        enterRetryingState();
    }
    else if (minimumState == FILE_PUBLISH_UPLOADED)
    {
        CLOG(INFO, "History") << "All file-puts succeeded";
        enterCommittingState();
    }
    else
    {
        CLOG(DEBUG, "History") << "Some file-puts still in progress";
        // Do nothing here; in-progress states have callbacks set up already
        // which will fire when they complete.
    }
}
コード例 #21
0
ファイル: gcov-12.c プロジェクト: ImmanuelHaffner/JACCo-old
int main ()
{
  return weak ();
}
コード例 #22
0
ファイル: FFL_Thread.cpp プロジェクト: lianhuaren/cocoa
	int Thread::_threadLoop(void* user)
	{
		Thread* const self = static_cast<Thread*>(user);

		sp<Thread> strong(self->mThreadData->mHoldSelf);
		wp<Thread> weak(strong);
		self->mThreadData->mHoldSelf.clear();
		bool first = true;
		bool exec_thread_exit = false;

		{//
		 //  等待run函数返回成功
		//
			CMutex::Autolock _l(self->mThreadData->mLock);
			if (self->mThreadData->mThread == NULL) {
				self->mThreadData->mThreadReadyCondition.wait(self->mThreadData->mLock);
			}
		}

		//
		//  保存一下线程名称
		//	
        unsigned long tid=self->mThreadData->mTid = FFL_CurrentThreadID();
		char threadName[256] = { 0 };
		const  char* tmpName = FFL_GetThreadName(self->mThreadData->mThread);
		if (tmpName != NULL && tmpName[0] != 0) {
			memcpy(threadName, tmpName, FFL_MIN(strlen(tmpName), 255));
		}
		INTERNAL_FFL_LOG_DEBUG("Thread(%d)(%s) run", tid, threadName);

		if (self->mThreadData->mPriority != FFL_THREAD_PRIORITY_NORMAL) {
			FFL_SetThreadPriority(self->mThreadData->mPriority);
		}


		self->threadLoopStart();		
		do {
			bool result;
			if (first) {
				first = false;
				self->mThreadData->mStatus = self->readyToRun();
				result = (self->mThreadData->mStatus == FFL_NO_ERROR);

				if (result && !self->exitPending()) {
					// Binder threads (and maybe others) rely on threadLoop
					// running at least once after a successful ::readyToRun()
					// (unless, of course, the thread has already been asked to exit
					// at that point).
					// This is because threads are essentially used like this:
					//   (new ThreadSubclass())->run();
					// The caller therefore does not retain a strong reference to
					// the thread and the thread would simply disappear after the
					// successful ::readyToRun() call instead of entering the
					// threadLoop at least once.
					result = self->threadLoop();
				}
			}
			else {
				result = self->threadLoop();
			}

			// establish a scope for mLock
			{
				CMutex::Autolock _l(self->mThreadData->mLock);
				if (result == false || self->mThreadData->mExitPending) {
					self->mThreadData->mExitPending = true;
					self->mThreadData->mRunning = false;
					
					// clear thread ID so that requestExitAndWait() does not exit if
					// called by a new thread using the same thread ID as this one.
					self->mThreadData->mThread = 0;
					
					self->threadLoopExit(self);
					exec_thread_exit = true;

					// note that interested observers blocked in requestExitAndWait are
					// awoken by broadcast, but blocked on mLock until break exits scope
					self->mThreadData->mThreadExitedCondition.broadcast();
					break;
				}
			}

			// Release our strong reference, to let a chance to the thread
			// to die a peaceful death.
			strong.clear();
			// And immediately, re-acquire a strong reference for the next loop
			strong = weak.promote();
		} while (!strong.is_empty());

		if(!exec_thread_exit)
		   self->threadLoopExit(0);

		INTERNAL_FFL_LOG_DEBUG("Thread(%d)(%s) exit", tid, threadName);
		return 0;
	}
コード例 #23
0
ファイル: Heap.cpp プロジェクト: sysrqb/chromium-src
void Heap::FinalizerOwner::finalize(Handle<Unknown> handle, void* context)
{
    Weak<JSCell> weak(Weak<JSCell>::Adopt, handle);
    Finalizer finalizer = reinterpret_cast<Finalizer>(context);
    finalizer(weak.get());
}
コード例 #24
0
ファイル: gcov-13.c プロジェクト: Sunmonds/gcc
int main ()
{
  return weak (); /* count(1) */
}
コード例 #25
0
void tst_QSharedPointer::basics()
{
    {
        QSharedPointer<Data> ptr;
        QWeakPointer<Data> weakref;

        QCOMPARE(sizeof(ptr), 2*sizeof(void*));
        QCOMPARE(sizeof(weakref), 2*sizeof(void*));
    }

    QFETCH(bool, isNull);
    Data *aData = 0;
    if (!isNull)
        aData = new Data;
    Data *otherData = new Data;
    QSharedPointer<Data> ptr(aData);

    {
        // basic self tests
        QCOMPARE(ptr.isNull(), isNull);
        QCOMPARE(bool(ptr), !isNull);
        QCOMPARE(!ptr, isNull);

        QCOMPARE(ptr.data(), aData);
        QCOMPARE(ptr.operator->(), aData);
        Data &dataReference = *ptr;
        QCOMPARE(&dataReference, aData);

        QVERIFY(ptr == aData);
        QVERIFY(!(ptr != aData));
        QVERIFY(aData == ptr);
        QVERIFY(!(aData != ptr));

        QVERIFY(ptr != otherData);
        QVERIFY(otherData != ptr);
        QVERIFY(! (ptr == otherData));
        QVERIFY(! (otherData == ptr));
    }
    QVERIFY(!ptr.d || ptr.d->weakref == 1);
    QVERIFY(!ptr.d || ptr.d->strongref == 1);

    {
        // create another object:
        QSharedPointer<Data> otherCopy(otherData);
        QVERIFY(ptr != otherCopy);
        QVERIFY(otherCopy != ptr);
        QVERIFY(! (ptr == otherCopy));
        QVERIFY(! (otherCopy == ptr));

        // otherData is deleted here
    }
    QVERIFY(!ptr.d || ptr.d->weakref == 1);
    QVERIFY(!ptr.d || ptr.d->strongref == 1);

    {
        // create a copy:
        QSharedPointer<Data> copy(ptr);
        QVERIFY(copy == ptr);
        QVERIFY(ptr == copy);
        QVERIFY(! (copy != ptr));
        QVERIFY(! (ptr != copy));
        QCOMPARE(copy, ptr);
        QCOMPARE(ptr, copy);

        QCOMPARE(copy.isNull(), isNull);
        QCOMPARE(copy.data(), aData);
        QVERIFY(copy == aData);
    }
    QVERIFY(!ptr.d || ptr.d->weakref == 1);
    QVERIFY(!ptr.d || ptr.d->strongref == 1);

    {
        // create a weak reference:
        QWeakPointer<Data> weak(ptr);
        QCOMPARE(weak.isNull(), isNull);
        QCOMPARE(!weak, isNull);
        QCOMPARE(bool(weak), !isNull);

        QVERIFY(ptr == weak);
        QVERIFY(weak == ptr);
        QVERIFY(! (ptr != weak));
        QVERIFY(! (weak != ptr));

        // create another reference:
        QWeakPointer<Data> weak2(weak);
        QCOMPARE(weak2.isNull(), isNull);
        QCOMPARE(!weak2, isNull);
        QCOMPARE(bool(weak2), !isNull);

        QVERIFY(weak2 == weak);
        QVERIFY(weak == weak2);
        QVERIFY(! (weak2 != weak));
        QVERIFY(! (weak != weak2));

        // create a strong reference back:
        QSharedPointer<Data> strong(weak);
        QVERIFY(strong == weak);
        QVERIFY(strong == ptr);
        QCOMPARE(strong.data(), aData);
    }
    QVERIFY(!ptr.d || ptr.d->weakref == 1);
    QVERIFY(!ptr.d || ptr.d->strongref == 1);

    // aData is deleted here
}