Пример #1
0
static void DaoState_WaitFor2( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoState *self = (DaoState*)DaoValue_CastCstruct( p[0], NULL );
	int eq = 0, res = 1;
	DaoValue *state = p[1];
	float timeout;
	DaoCondVar *condvar = NULL;
	DaoMutex_Lock( self->lock );
	if( !DaoValue_Compare( self->state, state ) )
		eq = 1;
	else{
		condvar = (DaoCondVar*)DaoMap_GetValue( self->demands, state );
		if( !condvar ){
			condvar = DaoCondVar_New();
			DaoMap_Insert( self->demands, state, (DaoValue*)condvar );
		}
	}
	DaoMutex_Unlock( self->lock );
	if( !eq ){
		DaoMutex_Lock( self->defmtx );
		timeout = DaoValue_TryGetFloat( p[2] );
		if( timeout > 0 )
			do
				res = !DaoCondVar_TimedWait( condvar, self->defmtx, timeout );
			while( res && DaoValue_Compare( self->state, state ) );
		else if( timeout == 0 )
			res = 0;
		else
			do
				DaoCondVar_Wait( condvar, self->defmtx );
			while( DaoValue_Compare( self->state, state ) );
		DaoMutex_Unlock( self->defmtx );
	}
	DaoProcess_PutInteger( proc, res );
}
Пример #2
0
static void DaoQueue_Merge( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL );
	DaoQueue *other = (DaoQueue*)DaoValue_CastCstruct( p[1], NULL );
	int merged = 0;
	DaoMutex_Lock( self->mtx );
	DaoMutex_Lock( other->mtx );
	if( !self->capacity || self->size + other->size <= self->capacity ){
		if( self->size && other->size ){
			self->tail->next = other->head;
			other->head->previous = self->tail;
		}
		else if( !self->size ){
			self->head = other->head;
			self->tail = other->tail;
			DaoCondVar_BroadCast( self->popvar );
		}
		self->size += other->size;
		if( other->capacity && other->size == other->capacity )
			DaoCondVar_BroadCast( other->pushvar );
		other->size = 0;
		other->head = other->tail = NULL;
		merged = 1;
	}
	DaoMutex_Unlock( self->mtx );
	DaoMutex_Unlock( other->mtx );
	if( !merged )
		DaoProcess_RaiseException( proc, DAO_ERROR, "Merging exceeds the queue capacity" );
}
Пример #3
0
static void DaoState_Value( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoState *self = (DaoState*)DaoValue_CastCstruct( p[0], NULL );
	DaoMutex_Lock( self->lock );
	DaoProcess_PutValue( proc, self->state );
	DaoMutex_Unlock( self->lock );
}
Пример #4
0
static void DaoQueue_Size( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL );
	int size;
	DaoMutex_Lock( self->mtx );
	size = self->size;
	DaoMutex_Unlock( self->mtx );
	DaoProcess_PutInteger( proc, size );
}
Пример #5
0
static void DaoMutex_Lib_Protect( DaoProcess *proc, DaoValue *p[], int n )
{
	DaoMutex *self = (DaoMutex*) p[0];
	DaoVmCode *sect = DaoGetSectionCode( proc->activeCode );
	if( sect == NULL || DaoMT_PushSectionFrame( proc ) == 0 ) return;
	DaoMutex_Lock( self );
	DaoProcess_Execute( proc );
	DaoMutex_Unlock( self );
	DaoProcess_PopFrame( proc );
}
Пример #6
0
static void DaoState_Waitlist( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoState *self = (DaoState*)DaoValue_CastCstruct( p[0], NULL );
	DaoList *list = DaoProcess_PutList( proc );
	DNode *node;
	DaoMutex_Lock( self->lock );
	node = DaoMap_First( self->demands );
	while( node ){
		DaoList_PushBack( list, DNode_Key( node ) );
		node = DaoMap_Next( self->demands, node );
	}
	DaoMutex_Unlock( self->lock );
}
Пример #7
0
static void DaoState_Set( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoState *self = (DaoState*)DaoValue_CastCstruct( p[0], NULL );
	DNode *node;
	DaoMutex_Lock( self->lock );
	DaoValue_Copy( p[1], &self->state );
	node = DaoMap_First( self->demands );
	while( node && DaoValue_Compare( DNode_Key( node ), self->state ) )
		node = DaoMap_Next( self->demands, node );
	if( node ){
		DaoCondVar_BroadCast( (DaoCondVar*)DNode_Value( node ) );
		DaoMap_Erase( self->demands, DNode_Key( node ) );
	}
	DaoMutex_Unlock( self->lock );
}
Пример #8
0
static void DaoState_TestSet( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoState *self = (DaoState*)DaoValue_CastCstruct( p[0], NULL );
	int set = 0;
	DNode *node;
	DaoMutex_Lock( self->lock );
	if( !DaoValue_Compare( self->state, p[1] ) ){
		DaoValue_Copy( p[2], &self->state );
		set = 1;
		node = DaoMap_First( self->demands );
		while( node && DaoValue_Compare( DNode_Key( node ), self->state ) )
			node = DaoMap_Next( self->demands, node );
		if( node )
			DaoCondVar_BroadCast( (DaoCondVar*)DNode_Value( node ) );
	}
	DaoMutex_Unlock( self->lock );
	DaoProcess_PutInteger( proc, set );
}
Пример #9
0
static void DaoQueue_Pop( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL );
	QueueItem *item = NULL;
	DaoMutex_Lock( self->mtx );
	while( !self->size )
		DaoCondVar_Wait( self->popvar, self->mtx );
	item = self->head;
	self->head = item->next;
	if( !self->head )
		self->tail = NULL;
	else
		self->head->previous = NULL;
	if( self->capacity && self->size == self->capacity )
		DaoCondVar_Signal( self->pushvar );
	self->size--;
	DaoMutex_Unlock( self->mtx );
	DaoProcess_PutValue( proc, item->value );
	DaoGC_DecRC( item->value );
	dao_free( item );
}
Пример #10
0
static void DaoQueue_Push( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL );
	QueueItem *item = (QueueItem*)dao_malloc( sizeof(QueueItem) );
	item->value = NULL;
	DaoValue_Copy( p[1], &item->value );
	item->next = NULL;
	DaoMutex_Lock( self->mtx );
	while( self->capacity && self->size == self->capacity )
		DaoCondVar_Wait( self->pushvar, self->mtx );
	item->previous = self->tail;
	if( self->tail )
		self->tail->next = item;
	else{
		self->head = item;
		DaoCondVar_Signal( self->popvar );
	}
	self->tail = item;
	self->size++;
	DaoMutex_Unlock( self->mtx );
}
Пример #11
0
static void DaoQueue_TryPush( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL );
	QueueItem *item = (QueueItem*)dao_malloc( sizeof(QueueItem) );
	float timeout = DaoValue_TryGetFloat( p[2] );
	int pushable = 0, timed = 0;
	item->value = NULL;
	DaoValue_Copy( p[1], &item->value );
	item->next = NULL;
	DaoMutex_Lock( self->mtx );
	if( timeout == 0 )
		pushable = ( !self->capacity || self->size < self->capacity );
	else if( timeout < 0 ){
		while( self->capacity && self->size == self->capacity )
			DaoCondVar_Wait( self->pushvar, self->mtx );
		pushable = 1;
	}
	else{
		while( !timed && self->capacity && self->size == self->capacity )
			timed = DaoCondVar_TimedWait( self->pushvar, self->mtx, timeout );
		pushable = !timed;
	}
	if( pushable ){
		item->previous = self->tail;
		if( self->tail )
			self->tail->next = item;
		else{
			self->head = item;
			DaoCondVar_Signal( self->popvar );
		}
		self->tail = item;
		self->size++;
	}
	DaoMutex_Unlock( self->mtx );
	if( !pushable ){
		DaoGC_DecRC( item->value );
		dao_free( item );
	}
	DaoProcess_PutInteger( proc, pushable );
}
Пример #12
0
static void DaoQueue_TryPop( DaoProcess *proc, DaoValue *p[], int N )
{
	DaoQueue *self = (DaoQueue*)DaoValue_CastCstruct( p[0], NULL );
	QueueItem *item = NULL;
	float timeout = DaoValue_TryGetFloat( p[1] );
	int popable = 0, timed = 0;
	DaoMutex_Lock( self->mtx );
	if( timeout == 0 )
		popable = self->size;
	else if( timeout < 0 ){
		while( !self->size )
			DaoCondVar_Wait( self->popvar, self->mtx );
		popable = 1;
	}
	else{
		while( !timed && !self->size )
			timed = DaoCondVar_TimedWait( self->popvar, self->mtx, timeout );
		popable = !timed;
	}
	if( popable ){
		item = self->head;
		self->head = item->next;
		if( !self->head )
			self->tail = NULL;
		else
			self->head->previous = NULL;
		if( self->capacity && self->size == self->capacity )
			DaoCondVar_Signal( self->pushvar );
		self->size--;
	}
	DaoMutex_Unlock( self->mtx );
	DaoProcess_PutValue( proc, item? item->value : dao_none_value );
	if( item ){
		DaoGC_DecRC( item->value );
		dao_free( item );
	}
}
Пример #13
0
static void DaoMutex_Lib_Unlock( DaoProcess *proc, DaoValue *par[], int N )
{
	DaoMutex *self = (DaoMutex*) par[0];
	DaoMutex_Unlock( self );
}