/* assumed to be called after parsing class body */ void DaoClass_DeriveObjectData( DaoClass *self ) { DaoType *type; DaoValue *value; DArray *parents, *offsets; DString *mbs; DNode *search; daoint i, id, perm, index, offset = 0; self->objDefCount = self->objDataName->size; offset = self->objDataName->size; mbs = DString_New(1); parents = DArray_New(0); offsets = DArray_New(0); DaoClass_Parents( self, parents, offsets ); for( i=0; i<self->superClass->size; i++){ if( self->superClass->items.pValue[i]->type == DAO_CLASS ){ DaoClass *klass = self->superClass->items.pClass[i]; /* for properly arrangement object data: */ for( id=0; id<klass->objDataName->size; id ++ ){ DString *name = klass->objDataName->items.pString[id]; DaoVariable *var = klass->instvars->items.pVar[id]; var = DaoVariable_New( var->value, var->dtype ); DArray_Append( self->objDataName, name ); DArray_Append( self->instvars, var ); DaoValue_MarkConst( (DaoValue*) var->value ); } offset += klass->objDataName->size; } } for(i=1; i<parents->size; i++){ DaoClass *klass = parents->items.pClass[i]; offset = offsets->items.pInt[i]; /* plus self */ if( klass->type == DAO_CLASS ){ /* For object data: */ for( id=0; id<klass->objDataName->size; id ++ ){ DString *name = klass->objDataName->items.pString[id]; search = MAP_Find( klass->lookupTable, name ); perm = LOOKUP_PM( search->value.pInt ); /* NO deriving private member: */ if( perm <= DAO_DATA_PRIVATE ) continue; search = MAP_Find( self->lookupTable, name ); if( search == NULL ){ /* To not overide data and routine: */ index = LOOKUP_BIND( DAO_OBJECT_VARIABLE, perm, i, (offset+id) ); MAP_Insert( self->lookupTable, name, index ); } } } } self->derived = 1; DString_Delete( mbs ); DArray_Delete( parents ); DArray_Delete( offsets ); DaoObject_Init( & self->objType->value->xObject, NULL, 0 ); self->objType->value->xObject.trait &= ~DAO_VALUE_CONST; DaoValue_MarkConst( self->objType->value ); DaoValue_MarkConst( self->constants->items.pConst[1]->value ); /* ::default */ }
static void DaoClass_AddConst3( DaoClass *self, DString *name, DaoValue *data ) { DaoConstant *cst = DaoConstant_New( data ); DArray_Append( self->cstDataName, (void*)name ); DArray_Append( self->constants, cst ); DaoValue_MarkConst( cst->value ); }
/* // Only activate one event per channel: */ void DaoChannel_ActivateEvent( DaoChannel *self, int type ) { DaoCallServer *server = daoCallServer; DNode *node; daoint i; for(i=0; i<server->events2->size; ++i){ DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i]; if( event->type != type ) continue; if( DaoCallServer_CheckEvent( event, NULL, self ) ){ DArray_Append( server->events, event ); DArray_Erase( server->events2, i, 1 ); return; } } for(node=DMap_First(server->waitings); node; node=DMap_Next(server->waitings,node)){ DaoTaskEvent *event = (DaoTaskEvent*) node->value.pValue; if( event->type != type ) continue; if( DaoCallServer_CheckEvent( event, NULL, self ) ){ DArray_Append( server->events, event ); DMap_EraseNode( server->waitings, node ); return; } } }
/* // Activate all events waiting on a future value: */ void DaoFuture_ActivateEvent( DaoFuture *self ) { DaoCallServer *server = daoCallServer; DArray *array = DArray_New(0); DNode *node; daoint i; DMutex_Lock( & server->mutex ); for(i=0; i<server->events2->size; ++i){ DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i]; if( DaoCallServer_CheckEvent( event, self, NULL ) ){ event->state = DAO_EVENT_RESUME; DArray_Append( server->events, event ); DArray_Erase( server->events2, i, 1 ); i -= 1; } } for(node=DMap_First(server->waitings); node; node=DMap_Next(server->waitings,node)){ DaoTaskEvent *event = (DaoTaskEvent*) node->value.pValue; /* remove from timed waiting list: */ if( DaoCallServer_CheckEvent( event, self, NULL ) ){ event->state = DAO_EVENT_RESUME; DArray_Append( server->events, event ); DArray_Append( array, node->key.pVoid ); } } for(i=0; i<array->size; i++) DMap_Erase( server->waitings, array->items.pVoid[i] ); DCondVar_Signal( & server->condv ); DMutex_Unlock( & server->mutex ); DArray_Delete( array ); }
void DaoxShader_AddShader( DaoxShader *self, int type, const char *codes ) { DString source = DString_WrapMBS( codes ); switch( type ){ case GL_VERTEX_SHADER : DArray_Append( self->vertexSources, & source ); break; case GL_FRAGMENT_SHADER : DArray_Append( self->fragmentSources, & source ); break; } }
static void DaoClass_AddConst3( DaoClass *self, DString *name, DaoValue *data ) { DaoConstant *cst = DaoConstant_New( data ); DArray_Append( self->cstDataName, (void*)name ); DArray_Append( self->constants, cst ); DaoValue_MarkConst( cst->value ); if( data->type == DAO_ROUTINE && data->xRoutine.routHost != self->objType ){ if( data->xRoutine.attribs & DAO_ROUT_VIRTUAL ){ /* data->xRoutine.overloads == NULL */ if( self->vtable == NULL ) self->vtable = DHash_New(0,0); MAP_Insert( self->vtable, data, data ); } } }
void DaoLexer_AppendToken( DaoLexer *self, DaoToken *token ) { DaoToken *tok; if( self->tokbuf->size == 0 ){ DArray_Append( self->tokens, token ); return; } tok = (DaoToken*) DArray_Back( self->tokbuf ); self->tokbuf->size -= 1; DaoToken_Assign( tok, token ); DArray_Append( self->tokens, NULL ); /* avoid copying; */ self->tokens->items.pToken[self->tokens->size-1] = tok; }
/* Backward traverse the macro units and set stopping tokens for each unit. * A stopping token is defined as the content of a macro unit of type DMACRO_TOK. * XXX, also define stopping token by DMACRO_BR units? */ static void DMacroGroup_SetStop( DMacroGroup *self, DArray *stops ) { DMacroGroup *group; daoint i, j; /* printf( "stop : %i\n", stops->size ); */ for(i=self->units->size-1; i>=0; i--){ DMacroUnit *unit = (DMacroUnit*) self->units->items.pVoid[i]; if( unit->type == DMACRO_GRP || unit->type == DMACRO_ALT ){ group = (DMacroGroup*) unit; /* self->stops as temporary array: */ DArray_Assign( self->stops, stops ); /* recursive set stopping tokens for macro groups: */ DMacroGroup_SetStop( group, self->stops ); /* if the group has to be presented at least once, * no propagating the stopping tokens to the previous macro units. */ if( group->repeat > DMACRO_ZERO_OR_MORE ) DArray_Clear( stops ); /* add stopping token, why only one ? XXX */ if( group->stops->size >0) DArray_PushFront( stops, group->stops->items.pString[0] ); }else if( unit->type == DMACRO_TOK ){ /* printf( "%s", unit->marker->mbs ); */ DArray_Clear( stops ); /* define a stopping token */ DArray_Append( stops, unit->marker ); DArray_Append( unit->stops, unit->marker ); }else{ /* printf( "%s", unit->marker->mbs ); */ for(j=0; j<stops->size; j++) DArray_Append( unit->stops, stops->items.pString[j] ); } /* printf( " : %i; ", unit->stops->size ); */ } if( self->repeat == DMACRO_ZERO_OR_MORE || self->repeat == DMACRO_ONE_OR_MORE ){ /* this is fine for DMACRO_GRP unit, what about DMACRO_ALT unit? XXX */ if( self->units->size >1 ){ DMacroUnit *first = (DMacroUnit*) self->units->items.pVoid[0]; DMacroGroup_AddStop( self, first->stops ); } } DArray_Assign( self->stops, stops ); /* printf( "group : %i\n", self->stops->size ); */ }
int DaoClass_AddGlobalVar( DaoClass *self, DString *name, DaoValue *data, DaoType *t, int s ) { int size = self->variables->size; int id = LOOKUP_BIND( DAO_CLASS_VARIABLE, s, 0, size ); DNode *node = MAP_Find( self->lookupTable, name ); if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED; if( data == NULL && t ) data = t->value; MAP_Insert( self->lookupTable, name, id ); DArray_Append( self->variables, DaoVariable_New( NULL, t ) ); DArray_Append( self->glbDataName, (void*)name ); if( data && DaoValue_Move( data, & self->variables->items.pVar[size]->value, t ) ==0 ) return -DAO_CTW_TYPE_NOMATCH; return id; }
int DaoClass_AddObjectVar( DaoClass *self, DString *name, DaoValue *deft, DaoType *t, int s ) { int id; DNode *node = MAP_Find( self->lookupTable, name ); if( node && LOOKUP_UP( node->value.pInt ) ) return -DAO_CTW_WAS_DEFINED; if( deft == NULL && t ) deft = t->value; id = self->objDataName->size; MAP_Insert( self->lookupTable, name, LOOKUP_BIND( DAO_OBJECT_VARIABLE, s, 0, id ) ); DArray_Append( self->objDataName, (void*)name ); DArray_Append( self->instvars, DaoVariable_New( deft, t ) ); DaoValue_MarkConst( self->instvars->items.pVar[ id ]->value ); return id; }
static void CHANNEL_Send( DaoProcess *proc, DaoValue *par[], int N ) { DaoValue *data; DaoFuture *future = DaoProcess_GetInitFuture( proc ); DaoChannel *self = (DaoChannel*) par[0]; float timeout = par[2]->xFloat.value; if( DaoProcess_CheckCB( proc, "cannot send/block inside code section method" ) ) return; if( self->cap <= 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "channel is closed" ); return; } data = DaoValue_DeepCopy( par[1] ); if( data == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR_PARAM, "invalid data for the channel" ); return; } //printf( "CHANNEL_Send: %p\n", event ); DMutex_Lock( & daoCallServer->mutex ); DArray_Append( self->buffer, data ); DaoChannel_ActivateEvent( self, DAO_EVENT_WAIT_RECEIVING ); DaoChannel_ActivateEvent( self, DAO_EVENT_WAIT_SELECT ); DCondVar_Signal( & daoCallServer->condv ); DMutex_Unlock( & daoCallServer->mutex ); if( self->buffer->size >= self->cap ){ DaoTaskEvent *event = DaoCallServer_MakeEvent(); DaoTaskEvent_Init( event, DAO_EVENT_WAIT_SENDING, DAO_EVENT_WAIT, future, self ); proc->status = DAO_PROCESS_SUSPENDED; proc->pauseType = DAO_PAUSE_CHANNEL_SEND; DaoCallServer_AddTimedWait( proc, event, timeout ); } }
static void FRAME_AddArray( DaoProcess *proc, DaoValue *p[], int N ) { DaoValue value = {0}; DaoxDataColumn *col; DaoxDataFrame *self = (DaoxDataFrame*) p[0]; DaoArray *array = (DaoArray*) p[1]; DString *lab = DaoValue_TryGetString( p[2] ); DaoType *etype = dao_array_types[array->etype]; daoint i, M = self->dims[0] * self->dims[2]; etype = etype->nested->items.pType[0]; DaoxDataFrame_Sliced( self ); col = DaoxDataFrame_MakeColumn( self, etype ); DArray_Append( self->columns, col ); DaoxDataColumn_Reset( col, M ); self->dims[1] += 1; if( lab->size ){ DString_ToMBS( lab ); DaoxDataFrame_AddLabel( self, DAOX_DF_COL, lab->mbs, self->dims[1]-1 ); } if( M > array->size ) M = array->size; for(i=0; i<M; ++i){ DaoArray_GetValue( array, i, & value ); DaoxDataColumn_SetCell( col, i, & value ); } M = self->dims[0] * self->dims[2]; for(i=array->size; i<M; ++i) DaoxDataColumn_SetCell( col, i, NULL ); }
static void FRAME_AddList( DaoProcess *proc, DaoValue *p[], int N ) { DaoxDataColumn *col; DaoxDataFrame *self = (DaoxDataFrame*) p[0]; DaoList *list = (DaoList*) p[1]; DString *lab = DaoValue_TryGetString( p[2] ); DaoType *etype = dao_type_any; daoint i, M = self->dims[0] * self->dims[2]; if( list->unitype && list->unitype->nested->size ){ DaoType *tp = list->unitype->nested->items.pType[0]; if( tp != NULL && !(tp->tid & DAO_ANY) ) etype = tp; } DaoxDataFrame_Sliced( self ); col = DaoxDataFrame_MakeColumn( self, etype ); DArray_Append( self->columns, col ); DaoxDataColumn_Reset( col, M ); self->dims[1] += 1; if( lab->size ){ DString_ToMBS( lab ); DaoxDataFrame_AddLabel( self, DAOX_DF_COL, lab->mbs, self->dims[1]-1 ); } if( M > list->items.size ) M = list->items.size; for(i=0; i<M; ++i) DaoxDataColumn_SetCell( col, i, list->items.items.pValue[i] ); M = self->dims[0] * self->dims[2]; for(i=list->items.size; i<M; ++i) DaoxDataColumn_SetCell( col, i, NULL ); }
static void DaoState_GetGCFields( void *p, DArray *values, DArray *arrays, DArray *maps, int remove ) { DaoState *self = (DaoState*)p; if( self->state ){ DArray_Append( values, self->state ); if( remove ) self->state = NULL; } }
void DaoClass_AddSuperClass( DaoClass *self, DaoValue *super ) { if( self->superClass->size >= DAO_MAX_PARENT ){ printf( "Error: too many parents (max. %i allowed) for the class: %s\n", DAO_MAX_PARENT, self->className->mbs ); return; } DArray_Append( self->superClass, super ); }
void DaoClass_AddSuperClass( DaoClass *self, DaoValue *super ) { if( self->parent ){ printf( "Error: parent class alread set!\n" ); return; } self->parent = super; DArray_Append( self->allBases, super ); }
void DaoxDataFrame_AddLabelGroup( DaoxDataFrame *self, int dim ) { if( dim >=0 && dim < 3 ){ DMap *labmap = DHash_New(D_STRING,0); DArray *labels = self->labels[dim]; self->groups[dim] = labels->size; DArray_Append( labels, labmap ); DMap_Delete( labmap ); } }
void DaoCallServer_AddTask( DThreadTask func, void *param, int now ) { int scheduled = 0; DaoCallServer *server = DaoCallServer_TryInit( mainVmSpace ); 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 ); } }
void DaoClass_MakeInterface( DaoClass *self ) { daoint i, j; DaoType *tp; DaoRoutine *meth; DaoInterface *inter = self->inter; DMap *deftypes = DHash_New(0,0); DArray_Clear( self->inter->supers ); DMap_Clear( self->inter->methods ); if( self->parent && self->parent->type == DAO_CLASS ) DArray_Append( inter->supers, self->parent->xClass.inter ); for(i=0; i<self->cstDataName->size; ++i){ DString *name = self->cstDataName->items.pString[i]; DaoValue *value = self->constants->items.pConst[i]->value; DaoRoutine *rout = (DaoRoutine*) value; DNode *it; if( value->type != DAO_ROUTINE ) continue; if( value->xRoutine.attribs & DAO_ROUT_DECORATOR ) continue; it = MAP_Find( self->lookupTable, rout->routName ); if( it == NULL || LOOKUP_PM( it->value.pInt ) != DAO_DATA_PUBLIC ) continue; DMap_Reset( deftypes ); DMap_Insert( deftypes, rout->routHost, inter->abtype ); if( rout->overloads == NULL ){ tp = DaoType_DefineTypes( rout->routType, rout->nameSpace, deftypes ); if( tp == NULL ) continue; /* TODO: handle error; */ meth = DaoRoutine_New( rout->nameSpace, inter->abtype, 0 ); meth->attribs = rout->attribs; DString_Assign( meth->routName, rout->routName ); GC_ShiftRC( tp, meth->routType ); meth->routType = tp; DaoMethods_Insert( inter->methods, meth, meth->nameSpace, meth->routHost ); }else{ for(j=0; j<rout->overloads->routines->size; ++j){ DaoRoutine *rout2 = rout->overloads->routines->items.pRoutine[j]; if( rout2->attribs & DAO_ROUT_DECORATOR ) continue; tp = DaoType_DefineTypes( rout2->routType, rout2->nameSpace, deftypes ); if( tp == NULL ) continue; /* TODO: handle error; */ meth = DaoRoutine_New( rout2->nameSpace, inter->abtype, 0 ); meth->attribs = rout2->attribs; DString_Assign( meth->routName, rout->routName ); GC_ShiftRC( tp, meth->routType ); meth->routType = tp; DaoMethods_Insert( inter->methods, meth, meth->nameSpace, meth->routHost ); } } } DMap_Delete( deftypes ); }
static void DaoCallServer_AddThread( DThreadTask func, void *param ) { DaoCallThread *calth; DaoCallServer_TryInit( 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 void DaoArray_MakeFullSlice( DaoArray *self, DArray *slices ) { DVector *tmp = DVector_New( sizeof(daoint) ); daoint i, D = self->ndim; /* slices: DArray<DVector<int> > */ DArray_Clear( slices ); DVector_Resize( tmp, 3 ); tmp->data.daoints[0] = SLICE_RANGE; tmp->data.daoints[2] = 0; for(i=0; i<D; ++i){ tmp->data.daoints[1] = self->dims[i]; DArray_Append( slices, tmp ); } if( D == 2 ){ tmp->data.daoints[1] = 1; DArray_Append( slices, tmp ); } DVector_Delete( tmp ); }
void DaoLexer_Reset( DaoLexer *self ) { daoint i; for(i=0; i<self->tokens->size; ++i){ /* No copying of tokens: */ DaoToken *token = self->tokens->items.pToken[i]; if( token->string.size > 64 ) DString_Clear( & token->string ); DArray_Append( self->tokbuf, token ); } self->tokens->size = 0; }
static void DaoQueue_GetGCFields( void *p, DArray *values, DArray *arrays, DArray *maps, int remove ) { DaoQueue *self = (DaoQueue*)p; while( self->tail != NULL ){ QueueItem *item = self->tail; self->tail = item->previous; if( item->value ){ DArray_Append( values, item->value ); if( remove ) item->value = NULL; } } }
static void DMacroGroup_FindVariables( DMacroGroup *self ) { DMacroGroup *group; daoint i, j; for(i=0; i<self->units->size; i++){ DMacroUnit *unit = (DMacroUnit*) self->units->items.pVoid[i]; if( unit->type == DMACRO_GRP || unit->type == DMACRO_ALT ){ group = (DMacroGroup*) unit; DMacroGroup_FindVariables( group ); for(j=0; j<group->variables->size; j++) DArray_Append( self->variables, group->variables->items.pVoid[j] ); }else if( unit->type >= DMACRO_VAR && unit->type <= DMACRO_IBL ){ DArray_Append( self->variables, (void*)unit->marker ); } } /* for(j=0; j<self->variables->size; j++) printf( "%p %s\n", self, self->variables->items.pString[j]->mbs ); */ }
DaoMacro* DaoMacro_New() { DaoMacro *self = (DaoMacro*) dao_malloc( sizeof(DaoMacro) ); DaoValue_Init( self, DAO_MACRO ); self->keyListApply = DArray_New(D_STRING); self->macroList = DArray_New(0); self->firstMacro = self; self->macroMatch = DMacroGroup_New(); self->macroApply = DMacroGroup_New(); DArray_Append( self->macroList, self ); return self; }
/* breadth-first search */ void DaoClass_Parents( DaoClass *self, DArray *parents, DArray *offsets ) { DaoValue *dbase; DaoClass *klass; DaoCdata *cdata; DaoTypeBase *typer; daoint i, j, offset; DArray_Clear( parents ); DArray_Clear( offsets ); DArray_Append( parents, self ); DArray_Append( offsets, self->objDataName->size ); for(i=0; i<parents->size; i++){ dbase = parents->items.pValue[i]; offset = offsets->items.pInt[i]; if( dbase->type == DAO_CLASS ){ klass = (DaoClass*) dbase; if( klass->parent ){ DaoClass *cls = (DaoClass*) klass->parent; DArray_Append( parents, klass->parent ); DArray_Append( offsets, (daoint) offset ); offset += (cls->type == DAO_CLASS) ? cls->objDataName->size : 0; } }else if( dbase->type == DAO_CTYPE ){ cdata = (DaoCdata*) dbase; typer = cdata->ctype->kernel->typer; for(j=0; j<DAO_MAX_CDATA_SUPER; j++){ if( typer->supers[j] == NULL ) break; DArray_Append( parents, typer->supers[j]->core->kernel->abtype->aux ); DArray_Append( offsets, (daoint) offset ); } } } }
void DaoxDataFrame_Reset( DaoxDataFrame *self ) { daoint i; for(i=0; i<self->columns->size; ++i){ DArray_Append( self->caches, self->columns->items.pVoid[i] ); } for(i=0; i<3; ++i){ self->dims[i] = 0; self->groups[i] = 0; DArray_Clear( self->labels[i] ); } GC_DecRC( self->original ); self->original = NULL; DArray_Clear( self->columns ); }
static void DaoCallServer_ActivateEvents() { DaoCallServer *server = daoCallServer; daoint i, j; if( server->idle != server->total ) return; if( server->events->size != 0 ) return; if( server->events2->size == 0 ) return; #ifdef DEBUG DaoStream_WriteMBS( mainVmSpace->errorStream, "WARNING: activating events!\n" ); #endif for(i=0; i<server->events2->size; ++i){ DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i]; DaoChannel *chan = event->channel; DaoFuture *fut = event->future; int move = 0, closed = 0; switch( event->type ){ case DAO_EVENT_WAIT_TASKLET : move = fut->precond == NULL || fut->precond->state == DAO_CALL_FINISHED; break; case DAO_EVENT_WAIT_RECEIVING : move = chan->buffer->size > 0; if( chan->cap <= 0 && chan->buffer->size == 0 ) move = 1; break; case DAO_EVENT_WAIT_SENDING : move = chan->buffer->size < chan->cap; break; case DAO_EVENT_WAIT_SELECT : if( event->channels == NULL ) continue; for(j=0; j<event->channels->size; ++j){ DaoChannel *chan = (DaoChannel*) event->channels->items.pValue[j]; closed += chan->cap <= 0; move = chan->buffer->size > 0; if( move ) break; } if( closed == event->channels->size ) move = 1; break; default: break; } if( move ){ DArray_Append( server->events, event ); DArray_Erase( server->events2, i, 1 ); i -= 1; } } DCondVar_Signal( & server->condv ); }
void DArray_Assign( DArray *left, DArray *right ) { daoint i; assert( left->type == right->type || (left->type == DAO_DATA_VALUE && right->type == 0) ); if( left == right ) return; if( right->size == 0 ){ DArray_Clear( left ); return; } if( left->type ){ DArray_Clear( left); for( i=0; i<right->size; i++ ) DArray_Append( left, right->items.pVoid[i] ); }else{ DArray_Resize( left, right->size, NULL ); for( i=0; i<right->size; i++ ) left->items.pVoid[i] = right->items.pVoid[i]; } }
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; }