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 ); }
static void DaoCallServer_Add( DaoTaskEvent *event ) { DaoCallServer *server; if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace ); server = daoCallServer; DMutex_Lock( & server->mutex ); DaoCallServer_AddEvent( event ); DCondVar_Signal( & server->condv ); DMutex_Unlock( & server->mutex ); DaoCallServer_TryAddThread( NULL, NULL, server->pending->size ); }
static void DaoCallServer_AddThread( DThreadTask func, void *param ) { DaoCallThread *calth; if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace ); calth = DaoCallThread_New( func, param ); DMutex_Lock( & daoCallServer->mutex ); daoCallServer->total += 1; DArray_Append( daoCallServer->threads, calth ); DMutex_Unlock( & daoCallServer->mutex ); DThread_Start( & calth->thread, (DThreadTask) DaoCallThread_Run, calth ); }
static DaoTaskEvent* DaoCallServer_MakeEvent() { DaoTaskEvent *event; DaoCallServer *server; if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace ); server = daoCallServer; DMutex_Lock( & server->mutex ); event = (DaoTaskEvent*) DArray_PopBack( server->caches ); if( event == NULL ) event = DaoTaskEvent_New(); DMutex_Unlock( & server->mutex ); return event; }
static void CHANNEL_New( DaoProcess *proc, DaoValue *par[], int N ) { DaoType *retype = DaoProcess_GetReturnType( proc ); DaoChannel *self = DaoChannel_New( retype, 0 ); CHANNEL_SetCap( self, par[0], proc ); if( DaoType_CheckPrimitiveType( retype->nested->items.pType[0] ) == 0 ){ DString *s = DString_New(1); DString_AppendMBS( s, "data type " ); DString_Append( s, retype->nested->items.pType[0]->name ); DString_AppendMBS( s, " is not supported for channel" ); DaoProcess_RaiseException( proc, DAO_ERROR, s->mbs ); DString_Delete( s ); } DaoProcess_PutValue( proc, (DaoValue*) self ); if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace ); }
void DaoCallServer_AddWait( DaoProcess *wait, DaoFuture *pre, double timeout ) { DaoFuture *future; DaoTaskEvent *event; DaoCallServer *server; if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace ); server = daoCallServer; future = DaoProcess_GetInitFuture( wait ); GC_ShiftRC( pre, future->precond ); future->precond = pre; future->state = DAO_CALL_PAUSED; event = DaoCallServer_MakeEvent(); DaoTaskEvent_Init( event, DAO_EVENT_WAIT_TASKLET, DAO_EVENT_WAIT, future, NULL ); DaoCallServer_AddTimedWait( wait, event, timeout ); }
void DaoCallServer_AddTask( DThreadTask func, void *param, int now ) { int scheduled = 0; DaoCallServer *server; if( daoCallServer == NULL ) DaoCallServer_Init( mainVmSpace ); server = daoCallServer; DMutex_Lock( & server->mutex ); if( server->idle > server->parameters->size || now == 0 ){ scheduled = 1; DArray_Append( server->functions, func ); DArray_Append( server->parameters, param ); DMap_Insert( server->pending, param, NULL ); DCondVar_Signal( & server->condv ); } DMutex_Unlock( & server->mutex ); if( scheduled ){ if( now == 0 ) DaoCallServer_TryAddThread( NULL, NULL, server->parameters->size ); }else{ DaoCallServer_AddThread( func, param ); } }
static DaoCallServer* DaoCallServer_TryInit( DaoVmSpace *vms ) { if( daoCallServer == NULL ) DaoCallServer_Init( vms ); return daoCallServer; }