Ejemplo n.º 1
0
sp_thread_result_t SP_THREAD_CALL wrapper_fn( void * arg )
{
	_thread * thread = (_thread*)arg;
	_threadpool * pool = (_threadpool*)thread->parent;

	for( ; 0 == ((_threadpool*)thread->parent)->tp_stop; ) {
		thread->fn( thread->arg );

		if( 0 != ((_threadpool*)thread->parent)->tp_stop ) break;

		sp_thread_mutex_lock( &thread->mutex );
		if( 0 == save_thread( thread->parent, thread ) ) {
			sp_thread_cond_wait( &thread->cond, &thread->mutex );
			sp_thread_mutex_unlock( &thread->mutex );
		} else {
			sp_thread_mutex_unlock( &thread->mutex );
			sp_thread_cond_destroy( &thread->cond );
			sp_thread_mutex_destroy( &thread->mutex );

			free( thread );
			break;
		}
	}

	sp_thread_mutex_lock( &pool->tp_mutex );
	pool->tp_total--;
	if( pool->tp_total <= 0 ) sp_thread_cond_signal( &pool->tp_empty );
	sp_thread_mutex_unlock( &pool->tp_mutex );

	return 0;
}
Ejemplo n.º 2
0
int dispatch_threadpool(threadpool from_me, dispatch_fn dispatch_to_here, void *arg)
{
	int ret = 0;

	_threadpool *pool = (_threadpool *) from_me;
	sp_thread_attr_t attr;
	_thread * thread = NULL;

	// add your code here to dispatch a thread
	sp_thread_mutex_lock( &pool->tp_mutex );
//	printf("==========dispatch_threadpool\n");
	while( pool->tp_index <= 0 && pool->tp_total >= pool->tp_max_index ) {
		//printf("all thread is busy!~~\n");
		sp_thread_cond_wait( &pool->tp_idle, &pool->tp_mutex );
	}

	if( pool->tp_index <= 0 ) {
		_thread * thread = ( _thread * )malloc( sizeof( _thread ) );
		memset( &( thread->id ), 0, sizeof( thread->id ) );
		sp_thread_mutex_init( &thread->mutex, NULL );
		sp_thread_cond_init( &thread->cond, NULL );
		thread->fn = dispatch_to_here;
		thread->arg = arg;
		thread->parent = pool;

		sp_thread_attr_init( &attr );
		sp_thread_attr_setdetachstate( &attr, SP_THREAD_CREATE_DETACHED );

		if( 0 == sp_thread_create( &thread->id, &attr, wrapper_fn, thread ) ) {
			pool->tp_total++;
		//	printf( "create thread#%ld\n", thread->id );
		} else {
			ret = -1;
			//printf( "cannot create thread\n" );
			sp_thread_mutex_destroy( &thread->mutex );
			sp_thread_cond_destroy( &thread->cond );
			free( thread );
		}
	} else {
		pool->tp_index--;
		thread = pool->tp_list[ pool->tp_index ];
		pool->tp_list[ pool->tp_index ] = NULL;

		thread->fn = dispatch_to_here;
		thread->arg = arg;
		thread->parent = pool;

		sp_thread_mutex_lock( &thread->mutex );
		sp_thread_cond_signal( &thread->cond ) ;
		sp_thread_mutex_unlock ( &thread->mutex );
	}

	sp_thread_mutex_unlock( &pool->tp_mutex );

	return ret;
}
Ejemplo n.º 3
0
void SP_IocpLFServer :: handleOneEvent()
{
	SP_Task * task = NULL;
	SP_Message * msg = NULL;

	sp_thread_mutex_lock( &mMutex );

	for( ; 0 == mIsShutdown && NULL == task && NULL == msg; ) {
		if( mEventArg->getInputResultQueue()->getLength() > 0 ) {
			task = (SP_Task*)mEventArg->getInputResultQueue()->pop();
		} else if( mEventArg->getOutputResultQueue()->getLength() > 0 ) {
			msg = (SP_Message*)mEventArg->getOutputResultQueue()->pop();
		}

		if( NULL == task && NULL == msg ) {
			SP_IocpEventCallback::eventLoop( mEventArg, mAcceptArg );
		}
	}

	sp_thread_mutex_unlock( &mMutex );

	if( NULL != task ) task->run();

	if( NULL != msg ) mCompletionHandler->completionMessage( msg );
}
Ejemplo n.º 4
0
void destroy_threadpool(threadpool destroyme)
{
	_threadpool *pool = (_threadpool *) destroyme;

	// add your code here to kill a threadpool
	int i = 0;

	sp_thread_mutex_lock( &pool->tp_mutex );

	if( pool->tp_index < pool->tp_total ) {
		printf( "waiting for %d thread(s) to finish\n", pool->tp_total - pool->tp_index );
		sp_thread_cond_wait( &pool->tp_full, &pool->tp_mutex );
	}

	pool->tp_stop = 1;

	for( i = 0; i < pool->tp_index; i++ ) {
		_thread * thread = pool->tp_list[ i ];

		sp_thread_mutex_lock( &thread->mutex );
		sp_thread_cond_signal( &thread->cond ) ;
		sp_thread_mutex_unlock ( &thread->mutex );
	}

	if( pool->tp_total > 0 ) {
		printf( "waiting for %d thread(s) to exit\n", pool->tp_total );
		sp_thread_cond_wait( &pool->tp_empty, &pool->tp_mutex );
	}

	for( i = 0; i < pool->tp_index; i++ ) {
		free( pool->tp_list[ i ] );
		pool->tp_list[ i ] = NULL;
	}

	sp_thread_mutex_unlock( &pool->tp_mutex );

	pool->tp_index = 0;

	sp_thread_mutex_destroy( &pool->tp_mutex );
	sp_thread_cond_destroy( &pool->tp_idle );
	sp_thread_cond_destroy( &pool->tp_full );
	sp_thread_cond_destroy( &pool->tp_empty );

	free( pool->tp_list );
	free( pool );
}
Ejemplo n.º 5
0
void SP_OnlineSidList :: add( SP_Sid_t sid )
{
	sp_thread_mutex_lock( &mMutex );

	mList.add( sid );

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 6
0
void SP_OnlineManager :: add( SP_OnlineInfo_t * info )
{
	sp_thread_mutex_lock( &mMutex );

	mList.append( info );

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 7
0
void SP_BlockingQueue :: push( void * item )
{
	sp_thread_mutex_lock( &mMutex );

	mQueue->push( item );

	sp_thread_cond_signal( &mCond );

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 8
0
void SP_CacheItem :: release()
{
	int refCount = 1;

	sp_thread_mutex_lock( &mMutex );
	mRefCount--;
	refCount = mRefCount;
	sp_thread_mutex_unlock( &mMutex );

	if( refCount <= 0 ) delete this;
}
Ejemplo n.º 9
0
void * SP_BlockingQueue :: top()
{
	void * ret = NULL;

	sp_thread_mutex_lock( &mMutex );

	ret = mQueue->top();

	sp_thread_mutex_unlock( &mMutex );

	return ret;
}
Ejemplo n.º 10
0
int SP_BlockingQueue :: getLength()
{
	int len = 0;

	sp_thread_mutex_lock( &mMutex );

	len = mQueue->getLength();

	sp_thread_mutex_unlock( &mMutex );

	return len;
}
/*
Caller MUST be holding the mutex lock; the
lock is released and the caller is blocked waiting
on 'cond'. When 'cond' is signaled, the mutex
is re-acquired before returning to the caller.
*/
int sp_thread_cond_wait( sp_thread_cond_t * cond, sp_thread_mutex_t * mutex )
{
	int ret = 0;

	sp_thread_mutex_unlock( mutex );

	ret = WaitForSingleObject( *cond, INFINITE );

	sp_thread_mutex_lock( mutex );

	return WAIT_OBJECT_0 == ret ? 0 : GetLastError();
}
Ejemplo n.º 12
0
int SP_OnlineManager :: getCount()
{
	int count = 0;

	sp_thread_mutex_lock( &mMutex );

	count = mList.getCount();

	sp_thread_mutex_unlock( &mMutex );

	return count;
}
Ejemplo n.º 13
0
void SP_OnlineSidList :: remove( SP_Sid_t sid )
{
	sp_thread_mutex_lock( &mMutex );

	for( int i = 0; i < mList.getCount(); i++ ) {
		SP_Sid_t theSid = mList.get( i );
		if( theSid.mKey == sid.mKey && theSid.mSeq == sid.mSeq ) {
			mList.take( i );
			break;
		}
	}

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 14
0
void SP_OnlineManager :: remove( SP_Sid_t sid )
{
	sp_thread_mutex_lock( &mMutex );

	for( int i = 0; i < mList.getCount(); i++ ) {
		SP_OnlineInfo_t * info = (SP_OnlineInfo_t*)mList.getItem( i );
		SP_Sid_t theSid = info->mSid;
		if( theSid.mKey == sid.mKey && theSid.mSeq == sid.mSeq ) {
			mList.takeItem( i );
			free( info );
			break;
		}
	}

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 15
0
void * SP_BlockingQueue :: pop()
{
	void * ret = NULL;

	sp_thread_mutex_lock( &mMutex );

	if( mQueue->getLength() == 0 ) {
		sp_thread_cond_wait( &mCond, &mMutex );
	}

	ret = mQueue->pop();

	sp_thread_mutex_unlock( &mMutex );

	return ret;
}
Ejemplo n.º 16
0
void SP_OnlineSidList :: copy( SP_SidList * outList, SP_Sid_t * ignoreSid )
{
	sp_thread_mutex_lock( &mMutex );

	for( int i = 0; i < mList.getCount(); i++ ) {
		if( NULL != ignoreSid ) {
			SP_Sid_t theSid = mList.get( i );
			if( theSid.mKey == ignoreSid->mKey && theSid.mSeq == ignoreSid->mSeq ) {
				continue;
			}
		}

		outList->add( mList.get( i ) );
	}

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 17
0
void SP_OnlineManager :: copy( SP_SidList * outList, SP_Sid_t * ignoreSid )
{
	sp_thread_mutex_lock( &mMutex );

	for( int i = 0; i < mList.getCount(); i++ ) {
		SP_OnlineInfo_t * info = (SP_OnlineInfo_t*)mList.getItem( i );

		if( NULL != ignoreSid ) {
			SP_Sid_t theSid = info->mSid;
			if( theSid.mKey == ignoreSid->mKey && theSid.mSeq == ignoreSid->mSeq ) {
				continue;
			}
		}

		outList->add( info->mSid );
	}

	sp_thread_mutex_unlock( &mMutex );
}
Ejemplo n.º 18
0
int SP_OnlineManager :: getChatID( SP_Sid_t sid )
{
	int chatID = -1;

	sp_thread_mutex_lock( &mMutex );

	for( int i = 0; i < mList.getCount(); i++ ) {
		SP_OnlineInfo_t * info = (SP_OnlineInfo_t*)mList.getItem( i );
		SP_Sid_t theSid = info->mSid;
		if( theSid.mKey == sid.mKey && theSid.mSeq == sid.mSeq ) {
			chatID = info->mChatID;
			break;
		}
	}

	sp_thread_mutex_unlock( &mMutex );

	return chatID;
}
Ejemplo n.º 19
0
int save_thread( _threadpool * pool, _thread * thread )
{
	int ret = -1;

	sp_thread_mutex_lock( &pool->tp_mutex );

	if( pool->tp_index < pool->tp_max_index ) {
		pool->tp_list[ pool->tp_index ] = thread;
		pool->tp_index++;
		ret = 0;

		sp_thread_cond_signal( &pool->tp_idle );

		if( pool->tp_index >= pool->tp_total ) {
			sp_thread_cond_signal( &pool->tp_full );
		}
	}

	sp_thread_mutex_unlock( &pool->tp_mutex );

	return ret;
}
Ejemplo n.º 20
0
void SP_CacheItem :: addRef()
{
	sp_thread_mutex_lock( &mMutex );
	mRefCount++;
	sp_thread_mutex_unlock( &mMutex );
}