示例#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);
    }
示例#2
0
 void tasklet_service::before_start_tasklet(tasklet& tasklet_)
 {
     if(_stop)
     {
         throw stop_exception();
     }
 }
示例#3
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);
    }
示例#4
0
	void simple_socket_stoppable::wait_for_read () {
		if (fd_to_monitor == INVALID_SOCKET) return;
		fd_set select_fds;
		FD_ZERO(&select_fds);
		FD_SET(sock, &select_fds);
		FD_SET(fd_to_monitor, &select_fds);
		timeval timeout_copy = *timeout; // For Linux
		timeval* select_tm = (timeout_action == timeout_act::NO_TIMEOUT) ? NULL : &timeout_copy;
		int selcode = select(((fd_to_monitor > sock) ? fd_to_monitor : sock), &select_fds, NULL, NULL, select_tm);
		if (selcode == SOCKET_ERROR) throw other_error("select() error in stoppable socket");
		if (selcode) {
			if (FD_ISSET(sock, &select_fds)) return;
			else throw stop_exception(context, fd_to_monitor);
		} else {
			if (timeout_action == timeout_act::RAISE_STOP) throw stop_exception(context, fd_to_monitor);
			else throw io_error(io_error::READ);
		}
	}
示例#5
0
 void tasklet_service::send(tasklet& target, tasklet& sender, const message& msg)
 {
     if(_stop)
     {
         throw stop_exception();
     }
     _channel_manager.dispatch(target._channel, msg);
     yield(sender);
 }
示例#6
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);
 }
示例#7
0
 void threadlet::loop()
 {
     if (_plast_finished_tasklet != NULL)
     {
         delete _plast_finished_tasklet;
         _plast_finished_tasklet = NULL;
     }
     threadlet_lock lock(this);
     _pcurrent_tasklet = &_ptasklet_service->pop_tasklet();
     if (_stop)
     {
         lock.unlock();
         assert(_pcurrent_tasklet != NULL);
         delete _pcurrent_tasklet;
         throw stop_exception();
     }
     switch_tasklet(*_pcurrent_tasklet);
 }
示例#8
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);
     }
 }
示例#9
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;
 }