⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usersync.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		{
		UserThread *pTheThread = tWaiting.SelectNextThread();
		if ( !pTheThread )
			{ break; };
		pTheThread->MakeRunnable( this );
		};

	/* --- abort any blocks --- */
	AbortBlocks( 0 );

	/* --- clear other values --- */
	ulData = 0;
#if DEBUG>=20
	CERR << "User Thread end of Cleanup(): " << (void *)this << endl;
	DbgWrite( CERR );
	CERR << endl;
#endif
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	virtual, public
 Description:
\*___________________________________________________________________________*/
bool UserThread::SetPriority( int iThePriority )
{
	if (!(	iThePriority <= PITHREAD_PRIORITY_HIGHEST &&
			iThePriority >= PITHREAD_PRIORITY_LOW ) )
		{ return false; };
	int iOldPriority = iPriority; 
	InternalSetPriority( iThePriority );
	if ( ___pTheCurrentThread != this )
		{
		___pLatentThreads->ChangeThreadPriority( this, iOldPriority,
			iPriority );
		};

	/* --- assume correct priorities --- */
	StackContextSwitch();
	return true;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	private
 Description:
	Return true if the priority was changed, else false.
\*___________________________________________________________________________*/
bool UserThread::InternalSetPriority( int iNewPriority )
{
	if ( iNewPriority == iPriority )
		{ return false; };
#if DEBUG>=20
		CERR << (void *)this
			<< "UserThread::InternalSetPriority(): changing priority from "
			<< iPriority << " to " << iNewPriority << endl;
#endif
	/* ---
	Change the priority of this thread wherever else it is 
	recorded
	--- */
	if ( pThread )
		{
		pThread->tWaiting.ChangeThreadPriority( this, iPriority,
			iNewPriority );
		};
	if ( pSemaphore )
		{
		pSemaphore->tWaiting.ChangeThreadPriority( this, iPriority,
			iNewPriority );
		};
	iPriority = iNewPriority;
	return true;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
bool UserThread::InternalTerminate( unsigned long ulTheStatus )
{
	ulStatus = ulTheStatus;
	assert( !bIsTerminated );
	if ( ___pTheCurrentThread == this )
		{
		StackUnwind();
		return true;		/* this is never reached */
		}
	else
		{
		___pLatentThreads->RemoveThread( this );
		___pExitingThread = this;
		StackContextSwitch();
		return true;
		};
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
int UserThread::PutToSleep( int iFD, int iFlags, int iTimeout )
{
	pPoll = PI_NEW( PollInfo( iFD, iFlags, iTimeout ) );
	___pThePoller->AddThread( this );
	StackContextSwitch();
	int iTmp = iNextReturnCode;
	iNextReturnCode = 0;
	return iTmp;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void UserThread::MakeRunnable( int iThePollResult )
{
	assert( pPoll );
	___pThePoller->RemoveThread( this );
	PI_DELETE( pPoll );
	pPoll = 0;
	iNextReturnCode = iThePollResult;		
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void UserThread::AbortBlocks( int iWhy )
{
	/* --- notify any objects that we are blocking on --- */	

	/* --- thread --- */
	if ( pThread )
		{ pThread->GaveUpWaiting( this ); };
	pThread = 0;

	/* --- mutex and semaphores --- */
	if ( pSemaphore )
		{ pSemaphore->GaveUpWaiting( this ); };
	pSemaphore = 0;
	
	/* --- sleep, file descriptor poll --- */
	if ( pPoll )
		{ MakeRunnable( iWhy ); };

	/* --- suspension --- */
	bSuspended = false;

	iNextReturnCode = iWhy;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
	Get the register context block for a thread
\*___________________________________________________________________________*/
size_t *__Pi_GetThreadContext( void *pThread )
{
	return ((UserThread *)pThread )->GetContext();
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
	Add a thread into the pool of latent threads
\*___________________________________________________________________________*/
void __Pi_AddLatentThread( void *pThread )
{
	___pLatentThreads->AddThread( (UserThread *)pThread );
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void __Pi_BeginThread( void *pThread )
{
	UserThread *pNewThread = (UserThread *)pThread;
	pNewThread->BeginThread();
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void __Pi_UnwindThreadStack( void *pThread )
{
	((UserThread *)pThread)->StackUnwind();
}
/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void *__Pi_SelectNextRunnableThread()
{
	/* ---
	Must get another thread or cause deadlock
	--- */
	return ___pLatentThreads->SelectNextRunnableThread( 1 );
}

/*___________________________________________________________________________*\
 *
 Function:	StackContextSwitch()
 Synopsis:
 Description:
	This is a very specical function. It swaps out the stack and so does
	a 'return' into another thread

	See Asm.cpp for an explaination.

	Returns non-zero if the thread was changed. This is useful internally
	for optimizing yield.

	NOTE: That optimization is disable for this entire file because of
	bad things that happen when ___pTheCurrent and ___pPlaceholer are
	optimized into local variables with __Pi_StackContextSwitch() in the
	middle.
\*___________________________________________________________________________*/
/* NOTE: temporary */
static UserThread *___pPlaceholder;
/* NOTE: end temporary */
int StackContextSwitch( void )
{
	int iFlag;

	UserThread *pNextThread = 0;
	if ( ___pNewThread )
		{
		iFlag = SCHED_BEGIN;
		pNextThread = ___pNewThread; 
		___pNewThread = 0;
		}
	else if ( ___pExitingThread )
		{
		iFlag = SCHED_EXIT;
		pNextThread = ___pExitingThread; 
		___pExitingThread = 0;
		}
	else
		{
		iFlag = SCHED_NEXT;
#if 0
		pNextThread = ___pLatentThreads->SelectNextRunnableThread( 0 );
		if ( !pNextThread )
			{
			/* --- don't switch context --- */
			return 0;
			};
#endif
		};

	___pPlaceholder = ___pTheCurrentThread;

#if DEBUG>=15
	CERR << "Before __Pi_StackContextSwitch()" << endl;
	DbgWriteAllThreads( CERR );
#endif

	__Pi_StackContextSwitch(
		(void **)&( ___pTheCurrentThread ),		/* address of thread pointer */
		pNextThread,	
		iFlag );								/* action to take */

#if DEBUG>=15
	CERR << "After __Pi_StackContextSwitch()" << endl;
	DbgWriteAllThreads( CERR );
#endif

#if 0
	return 1;
#else
	return ___pPlaceholder==___pTheCurrentThread ? 0 : 1;
#endif
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void Internal_InitThreads()
{
	if ( ___pLatentThreads )
	assert( !___pLatentThreads );
	if ( ___pLatentThreads )
		{ return; /* already initialized */ };
	memset( aUsedKeys, 0, sizeof( int ) * PI_MAXTHREADKEYS );
	___pLatentThreads = PI_NEW( ThreadScheduler );

	/* ---
	create a structure for the current thread (the main thread)
	and set the global thread pointer 
	--- */
	___pTheMainThread = PI_NEW( UserThread(
					Platform::GetGlobalAllocator(), 0 ) );
	___pTheCurrentThread = ___pTheMainThread;
	___pThePoller = PI_NEW( Poller );
	assert( ___pThePoller );
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
	This function assumes that the main thread is executing this function.
\*___________________________________________________________________________*/
void Internal_CleanupThreads()
{
	assert( ___pLatentThreads );
	if ( !___pLatentThreads )
		{ return; /* never initialized */ };

	PI_DELETE( ___pThePoller );
	___pThePoller = 0;

	/* --- this must be the main thread --- */
	PIMUSTBETRUE( ___pTheMainThread == ___pTheCurrentThread );
	while( ___pLatentThreads->Size() )
		{ PI_DELETE( (UserThread *)___pLatentThreads->SelectNextThread() ); };	
	PI_DELETE( ___pLatentThreads );
	___pLatentThreads = 0;

	/* --- destroy the main thread object --- */
	PI_DELETE( ___pTheMainThread );
	___pTheMainThread = 0;
	___pTheCurrentThread = 0;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
void Platform::Internal_EnterThreads( void (* fn)(void) )
{
	/* ---
	Initialize global values, even tough there are declared static and
	so must be zero initialized on startup, the threads initialization	
	could happen multiple times, say because of hangup restart
	--- */
	___pLatentThreads = 0;			/* global thread scheduler */
	___pThePoller = 0;				/* polls on sockets/files */
	___pTheMainThread = 0;			/* the main thread */
	___pTheCurrentThread = 0;		/* the current thread */
	___pNewThread = 0;				/* a newly created thread */
	___pExitingThread = 0;			/* an exiting thread */
	iThreadsCreated = 0;			/* since initialization */

	Internal_InitThreads();
	if ( fn )
		{
		___pTheMainThread->Begin( (ThreadFn)fn,
			(unsigned long)0, PITHREAD_PRIORITY_MED, 0 );
		};
	Internal_CleanupThreads();
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*___________________________________________________________________________*/
Allocator *Platform::GetCurrentAllocator()
{
	return Platform::GetGlobalAllocator();
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	  static, public:
 Description:
\*___________________________________________________________________________*/
Semaphore *Platform::AllocLocalMutex()
{
	return PI_NEW( UserLocalSemaphore( 1, 1) );
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	  static, public:
 Description:
\*___________________________________________________________________________*/
Semaphore *Platform::AllocLocalSemaphore( int iInitialCount, int iMaxCount )
{
	return PI_NEW( UserLocalSemaphore( iInitialCount, iMaxCount ) );
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	  static, public:
 Description:
\*___________________________________________________________________________*/
Thread *Platform::AllocThread(
		void *pV,
		int iStackSize )
{
	Allocator *pAllocator = (Allocator *)pV;	/* LATER, for MSVC4.2 */
	Thread *pNewThread = PI_NEW( UserThread(
			pAllocator ? pAllocator : Platform::GetGlobalAllocator(),
			iStackSize ? iStackSize : PI_DEFAULTSTACKSIZE ) );
	return pNewThread;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	  static, public:
 Description:
\*___________________________________________________________________________*/
void Platform::YieldThread()
{
	/* 
	** It would be good at some point to get a more sophisticated yield
	** with a flag to indicate different flavours
	**
	**
	** For Example
	** -----------
	** Add code to make this sleep( 0 ) to yield the process
	** timeslice if no threads are available.......Done
	**
	*/
	if ( !StackContextSwitch() )
		{
		/* ---
		Thread was not switched out, yield process timeslice
		--- */
#if defined(CONFIG_OS_POSIX)
#	if !defined(CONFIG_NO_YIELD)
		::yield();
#	endif
#else
#	if defined(CONFIG_OS_WIN32)
		::Sleep( 0 );
#	elif defined(CONFIG_OS_WIN16)
		::Yield();
#	endif
#endif
		};
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	  static, public:
 Description:
\*___________________________________________________________________________*/
int Platform::WaitForThread( Thread *pThread )
{
	int iRet = ___pTheCurrentThread->WaitForThread( (UserThread *)pThread );
	if ( iRet!=0 )
		{ PIERROR(iRet); };
	return iRet;
}

/*___________________________________________________________________________*\
 *
 Function:
 Synopsis:	  static, public:
 Description:
\*___________________________________________________________________________*/
Thread *Platform::GetCurrentThread()
{
	return ___pTheCurrentThread;
}

/*___________________________________________________________________________*\
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -