Esempio n. 1
0
    message  tasklet_service::recv(tasklet& recver)
    {
        if(_stop)
        {
            throw stop_exception();
        }
        bool switched = false;
        while (_channel_manager.empty(recver._channel))
        {
            park(recver);
            if (empty_runnables())
            {
                switch_tasklet(recver);
            }
            else
            {
                switch_tasklet(recver, pop_runnable());
            }
            switched = true;
        }

        if (!switched)
        {
            yield(recver);
        }
        return _channel_manager.fetch(recver._channel);
    }
Esempio n. 2
0
    message  tasklet_service::recv(tasklet& recver, double timeout)
    {
        if(_stop)
        {
            throw stop_exception();
        }
        if (timeout == infinity)
        {
            return recv(recver);
        }

        bool switched = false;
        unsigned long long wake_ = now()+(int)(timeout*10);
        while (_channel_manager.empty(recver._channel))
        {
            recver._state = timeout_waitting;
            recver._wake = wake_;
            _sleepers.insert(&recver);
            if (empty_runnables())
            {
                switch_tasklet(recver);
            }
            else
            {
                switch_tasklet(recver, pop_runnable());
            }
            switched = true;
    }

        if (!switched)
        {
            yield(recver);
        }
        return _channel_manager.fetch(recver._channel);
    }
Esempio n. 3
0
static void schedule(struct thread *t)
{
	struct thread *current = current_thread();

	/* If t is NULL need to find new runnable thread. */
	if (t == NULL) {
		if (thread_list_empty(&runnable_threads))
			die("Runnable thread list is empty!\n");
		t = pop_runnable();
	} else {
		/* current is still runnable. */
		push_runnable(current);
	}
	switch_to_thread(t->stack_current, &current->stack_current);
}
Esempio n. 4
0
 void tasklet_service::yield(tasklet& tasklet_)
 {
     if(_stop)
     {
         throw stop_exception();
     }
     if (empty_runnables())
     {
         return;
     }
     push_runnable(tasklet_);
     assert(!empty_runnables());
     tasklet& next = pop_runnable();
     switch_tasklet(tasklet_, next);
 }
Esempio n. 5
0
 void tasklet_service::sleep(tasklet& tasklet_, double timeout)
 {
     if(_stop)
     {
         throw stop_exception();
     }
     tasklet_._state = sleeping;
     tasklet_._wake = now()+(int)(timeout*10);
     _sleepers.insert(&tasklet_);
     if (empty_runnables())
     {
         switch_tasklet(tasklet_);
     }
     else
     {
         tasklet& next_tasklet = pop_runnable();
         switch_tasklet(tasklet_, next_tasklet);
     }
 }
Esempio n. 6
0
 tasklet& tasklet_service::pop_tasklet()
 {
     tasklet* ptasklet = NULL;
     while (!ptasklet && !_stop)
     {
         if (empty_runnables())
         {
             //这里本来可能引发因为_condition.wait释放_mutex导致的线程安全问题
             //但是很幸运的是,pop_tasklet只被threadlet::loop调用,这样就正好不会引发线程安全问题了
             _condition.wait();
         }
         else
         {
             assert(!empty_runnables());
             ptasklet = &pop_runnable();
         }
     }
     if (_stop && !ptasklet)
     {
         throw stop_exception();
     }
     return *ptasklet;
 }