Example #1
0
void CoroutineManager::runCorEvent(VarisEvent* event){
	size_t workerNumber = event->getCoroutine()->getId();
	Coroutine* coroutine = &(coroutines_[workerNumber]);
	lastCoroutine_ = curCoroutine_ ;
	curCoroutine_ = coroutine->getId();
	event->callback();
}
Example #2
0
	int64_t CoroutinePool::go(Coroutine::PFN_COROUTINE_TASK pfn, Object* arg, int64_t& cr_id){
		if(m_cleaning){
			WARN("coroutine pool go failed, cleaning");
			return -ErrorCode::SYSTEM_ERROR;
		}
		if(!pfn){
			return -ErrorCode::INVALID_ARG;
		}
		// prepare
		Coroutine* cr =_prepare_coroutine(pfn, arg);
		const int64_t result =_resume(cr, 0, 0);
		if(result == Coroutine::STATUS_WAITING){
			cr_id =cr->getId();
		}
		return result;
	}
Example #3
0
	bool CoroutineService::sleep(const int64_t secs){
		Coroutine* cr =Coroutine::Running();
		if(!cr){
			WARN("service %s(%lld) fail to sleep, in main thread", name(), (long long)m_id);
			return false;
		}
		if(m_processing_command){
			WARN("service %s(%lld) fail to sleep, in processing command", name(), (long long)m_id);
			return false;
		}
		const int64_t cr_id =cr->getId();
		m_sleeper_table->set(cr_id, SafeNew<Int64>(DateTime::Now() + secs));
		ASSERT(cr->yield(0, -1));
		m_sleeper_table->remove(cr_id);
		return true;
	}
Example #4
0
	/** coroutine manager **/
	void CoroutinePool::update(const int64_t now){
		// process timeout
		if(m_active_coroutine_table && m_active_coroutine_table->size()>0){
			// prepare
			Int64Array* ls =0;
			HashIterator* it =static_cast< HashIterator* >(m_active_coroutine_table->iterator());
			while(it->next()){
				Coroutine* cr =static_cast< Coroutine* >(it->getValue());
				if(cr->isWaitingAndExpire(now)){
					if(!ls){
						ls =SafeNew<Int64Array>();
					}
					ls->push_back(cr->getId());
				}
			}
			// resume
			if(ls && ls->size()>0){
				const int64_t n =ls->size();
				for(int64_t i=0; i<n; ++i){
					resume(ls->get(i), SafeNew<Error>(ErrorCode::TIMEOUT), 0);
				}
			}
		}
	}
Example #5
0
void CoroutineManager::runCoroutine(size_t workerNumber){
	Coroutine* coroutine = &(coroutines_[workerNumber]);
	lastCoroutine_ = curCoroutine_ ;
	curCoroutine_ = coroutine->getId();
	coroutine->work();
}
Example #6
0
	/** rpc **/
	Object* CoroutineService::rpc(const int64_t who, const int64_t to, const int64_t cmd, const int64_t res_proto_grp_id, Object* req_param){
		if(to == getId()){
			ERROR("service %s(%lld) can't request self", name(), (long long)m_id);
			return 0;
		}
		// prepare
		Coroutine* cr =Coroutine::Running();
		if(!cr){
			WARN("service %s(%lld) %lld fail to rpc to %lld, in main thread", name(), (long long)m_id, (long long)who, (long long)to);
			return 0;
		}
		ASSERT(cr->canYield());
		const int64_t cr_id =cr->getId();

		// set rpc info
		CoroutineRpcInfo* rpc_info =SafeNew<CoroutineRpcInfo>(res_proto_grp_id, cr_id);
		if(!set_rpc(rpc_info)){
			return 0;
		}
		const int64_t rpc_id =rpc_info->getId();

		// prepare packet
		PACKET packet;
		packet.from =getId();
		packet.to =to;
		packet.who =who;
		packet.sn =rpc_id;
		packet.command =cmd;
		packet.option =0;

		// request
		if(!DispatcherManager::RequestByObject(this, packet, req_param)){
			WARN("service %s(%lld) %lld fail to rpc to %lld, service not ready", name(), (long long)m_id, (long long)who, (long long)to);
			return 0;
		}
		rpc_info->set(rpc_id, this);
		ENSURE(cr->yield(0, rpc_id));

		// process respond
		if(Command* respond =dynamic_cast< Command* >(cr->getResumeParam())){
			// prepare
			const PACKET res_packet =respond->getPacket();
			if(res_packet.sn != static_cast<uint64_t>(rpc_id)){
				WARN("service %s(%lld) %lld fail to rpc to %lld, rpc id mismatch", name(), (long long)m_id, (long long)who, (long long)to);
				return 0;
			}
			// body is object pointer
			if(res_packet.option & OPT_BODY_IS_OBJECT_POINTER){
				return respond;
			}
			// body is protocol
			if(res_proto_grp_id>0){
				Bytes* res_bs =respond->getBody();
				const int64_t res_cmd =static_cast<int64_t>(res_packet.command);
				const int64_t group_id =res_proto_grp_id;
				const int64_t protocol_id =res_cmd;
				ProtocolBase* res_proto = ProtocolManager::CreateProtocol(group_id, protocol_id);
				if(!res_proto){
					ERROR("service %s(%lld) %lld fail to rpc to %lld, create protocol group %lld id %lld error", name(), (long long)m_id, (long long)who, (long long)to, (long long)group_id, (long long)protocol_id);
					return 0;
				}
				if(!res_proto->fromBytes(res_bs)){
					ERROR("service %s(%lld) %lld fail to rpc to %lld, unmarshal protocol name %s group %lld id %lld error", name(), (long long)m_id, (long long)who, (long long)to, res_proto->name(), (long long)group_id, (long long)protocol_id);
					return 0;
				}
				respond->setRequest(res_proto);
			}
			// body is not special
			return respond;
		}
		else{
			return cr->getResumeParam();
		}
	}