예제 #1
0
void DaoCallServer_AddTimedWait( DaoProcess *wait, DaoTaskEvent *event, double timeout )
{
	DaoCallServer *server = daoCallServer;

	/*
	// The "wait" process may not be running in the thread pool,
	// so it may have not been added to active process list.
	// It is necessary to add it to the active list now,
	// to avoid it being activated immediately after it is blocked.
	// Activating it immediately may cause a race condition,
	// because it may have not been blocked completely
	// (namely, it may be still running).
	*/
	DaoCallServer_MarkActiveProcess( wait, 1 );

	DMutex_Lock( & server->mutex );
	if( timeout >= 1E-27 ){
		server->timestamp.real = timeout + Dao_GetCurrentTime();
		server->timestamp.imag += 1;
		event->expiring = server->timestamp.real;
		DMap_Insert( server->waitings, & server->timestamp, event );
		DMap_Insert( server->pending, event, NULL );
		DCondVar_Signal( & server->condv2 );
	}else{
		event->expiring = -1.0;
		DaoCallServer_AddEvent( event );
		DCondVar_Signal( & server->condv );
	}
	DMutex_Unlock( & server->mutex );
}
예제 #2
0
파일: daoTasklet.c 프로젝트: hooloong/dao
void DaoCallServer_AddTimedWait( DaoProcess *wait, DaoTaskEvent *event, double timeout )
{
	DaoCallServer *server;
	if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace );
	server = daoCallServer;

	DMutex_Lock( & server->mutex );
	if( timeout >= 1E-27 ){
		server->timestamp.value.real = timeout + Dao_GetCurrentTime();
		server->timestamp.value.imag += 1;
		event->expiring = server->timestamp.value.real;
		DMap_Insert( server->waitings, & server->timestamp, event );
		DMap_Insert( server->pending, event, NULL );
		DCondVar_Signal( & server->condv2 );
	}else{
		event->expiring = -1.0;
		DaoCallServer_AddEvent( event );
		DCondVar_Signal( & server->condv );
	}
	if( wait->condv ){
		/*
		// Need to suspend the native thread, for suspending inside code sections
		// for functional methods such as std.iterate(), mt.iterate() etc:
		*/
		wait->pauseType = DAO_PAUSE_NATIVE_THREAD;
		if( timeout > 0 ){
			DCondVar_TimedWait( wait->condv, & server->mutex, timeout );
		}else{
			DCondVar_Wait( wait->condv, & server->mutex );
		}
		wait->status = DAO_PROCESS_RUNNING;
	}
	DMutex_Unlock( & server->mutex );
}
예제 #3
0
static void DaoCallServer_Timer( void *p )
{
	DaoCallServer *server = daoCallServer;
	double time = 0.0;
	daoint i, timeout;

	server->timing = 1;
	while( server->finishing == 0 || server->stopped != server->total ){
		DMutex_Lock( & server->mutex );
		while( server->waitings->size == 0 ){
			if( server->idle == server->total && server->events2->size ){
				DaoCallServer_ActivateEvents();
			}
			if( server->finishing && server->stopped == server->total ) break;
			DCondVar_TimedWait( & server->condv2, & server->mutex, 0.01 );
		}
		if( server->waitings->size ){
			DNode *node = DMap_First( server->waitings );
			time = node->key.pValue->xComplex.value.real;
			time -= Dao_GetCurrentTime();
			/* wait the right amount of time for the closest arriving timeout: */
			if( time > 0 ) DCondVar_TimedWait( & server->condv2, & server->mutex, time );
		}
		DMutex_Unlock( & server->mutex );
		if( server->finishing && server->stopped == server->total ) break;

		DMutex_Lock( & server->mutex );
		if( server->waitings->size ){ /* a new wait timed out: */
			DNode *node = DMap_First( server->waitings );
			time = Dao_GetCurrentTime();
			if( node->key.pValue->xComplex.value.real < time ){
				DaoTaskEvent *event = (DaoTaskEvent*) node->value.pVoid;
				event->state = DAO_EVENT_RESUME;
				event->timeout = 1;
				event->expiring = MIN_TIME;
				DArray_Append( server->events, node->value.pVoid );
				DMap_EraseNode( server->waitings, node );
			}
		}
		DCondVar_Signal( & server->condv );
		DMutex_Unlock( & server->mutex );
	}
	server->timing = 0;
}