CPDF_Rect CFFL_Utils::MaxRect(const CPDF_Rect & rect1,const CPDF_Rect & rect2)
{
	CPDF_Rect rcRet;

	rcRet.left = FFL_MIN(rect1.left,rect2.left);
	rcRet.bottom = FFL_MIN(rect1.bottom,rect2.bottom);
	rcRet.right = FFL_MAX(rect1.right,rect2.right);
	rcRet.top = FFL_MAX(rect1.top,rect2.top);

	return rcRet;
}
Esempio n. 2
0
	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;
	}