Esempio n. 1
0
int CAppCtrl::WorkInit()
{
	///停止主循环,待Init执行完毕后再执行主循环
	m_InitFinish = false;

	//初始化数据缓冲区
	m_stClientEncodeBuf.Attach(NULL, STREAM_BUFF_LENGTH, 0);
	m_stServerEncodeBuf.Attach(NULL, STREAM_BUFF_LENGTH, 0);
	m_stClientDecodeBuf.Attach(NULL, STREAM_BUFF_LENGTH, 0);

	///初始化後台連接
	int iRet = 0;
	bool NewServer = false;
	for (size_t i = 0; i < APP_CONF->SvrConnectInfo.size(); ++i)
	{
		CSvrConnectParam& stParam = APP_CONF->SvrConnectInfo[i];
		if(stParam.Index < 0 || stParam.Index >= EMAX_SVRCONN_COUNT)
		{
			SL_ERROR("invalid svr index %d, must in[0~%d]", stParam.Index, EMAX_SVRCONN_COUNT);
			return -1;
		}

		iRet = m_SvrConnect[stParam.Index].Init(GetEpoll(), stParam);
		CHECK_RETURN(iRet);

		iRet = m_SvrConnect[stParam.Index].ConnectSvr();
		CHECK_RETURN(iRet);
	}

	//加载业务so
	/*iRet = m_stSoLoader.LoadAppSo(APP_CONF->SoPath.c_str());
	CHECK_RETURN(iRet);
	CAppSoInf* pstAppSo = m_stSoLoader.CreateAppSo();
	if(pstAppSo == NULL)
	{
		return -1;
	}*/

	//调用so的onInit
	//iRet = SL_APPSO->OnInitConfig();
	CHECK_RETURN(iRet);
	SL_TRACE("appctrl init OnInitConfig");
	
	///内存预分配
	iRet = InitAppBuffer();
	CHECK_RETURN(iRet);
	SL_TRACE("appctrl init InitAppBuffer");

	/*iRet = SL_APPSO->OnInitBuffer();
	CHECK_RETURN(iRet);
	SL_TRACE("appctrl init OnInitBuffer");*/

	iRet = m_stShmBuff.CreateBuff("key/appsvr.key");
	CHECK_RETURN(iRet);
	SL_TRACE("appctrl init CreateBuff");

}
Esempio n. 2
0
int IoWait::WaitLoop(bool enable_block)
{
    int c = 0;
    for (;;) {
        std::list<CoTimerPtr> timers;
        timer_mgr_.GetExpired(timers, 128);
        if (timers.empty())
            break;

        c += timers.size();
        // 此处暂存callback而不是Task*,是为了block_cancel能够真实有效。
        std::unique_lock<LFLock> lock(timeout_list_lock_);
        timeout_list_.merge(std::move(timers));
    }

    std::unique_lock<LFLock> lock(epoll_lock_, std::defer_lock);
    if (!lock.try_lock())
        return c ? c : -1;

    ++loop_index_;
    int epoll_n = 0;
    if (IsEpollCreated())
    {
        static epoll_event *evs = new epoll_event[epoll_event_size_];
        for (int epoll_type = 0; epoll_type < 2; ++epoll_type)
        {
retry:
            int timeout = (enable_block && epoll_type == (int)EpollType::read && !c) ? epollwait_ms_ : 0;
            int n = epoll_wait(GetEpoll(epoll_type), evs, epoll_event_size_, timeout);
            if (n == -1) {
                if (errno == EINTR) {
                    goto retry;
                }
                continue;
            }

            epoll_n += n;
            DebugPrint(dbg_scheduler, "do epoll(%d) event, n = %d", epoll_type, n);
            for (int i = 0; i < n; ++i)
            {
                EpollPtr* ep = (EpollPtr*)evs[i].data.ptr;
                ep->revent = evs[i].events;
                Task* tk = ep->tk;
                ++tk->GetIoWaitData().wait_successful_;
                // 将tk暂存, 最后再执行Cancel, 是为了poll和select可以得到正确的计数。
                // 以防Task被加入runnable列表后,被其他线程执行
                epollwait_tasks_.insert(EpollWaitSt{tk, ep->io_block_id});
                DebugPrint(dbg_ioblock,
                        "task(%s) epoll(%s) trigger fd=%d io_block_id(%u) ep(%p) loop_index(%llu)",
                        tk->DebugInfo(), EpollTypeName(epoll_type),
                        ep->fdst->fd, ep->io_block_id, ep, (unsigned long long)loop_index_);
            }
        }

        for (auto &st : epollwait_tasks_)
            Cancel(st.tk, st.id);
        epollwait_tasks_.clear();
    }

    std::list<CoTimerPtr> timeout_list;
    {
        std::unique_lock<LFLock> lock(timeout_list_lock_);
        timeout_list_.swap(timeout_list);
    }

    for (auto &cb : timeout_list)
        (*cb)();

    // 由于epoll_wait的结果中会残留一些未计数的Task*,
    //     epoll的性质决定了这些Task无法计数, 
    //     所以这个析构的操作一定要在epoll_lock的保护中做
    std::vector<SList<Task>> delete_lists;
    Task::PopDeleteList(delete_lists);
    for (auto &delete_list : delete_lists)
        for (auto it = delete_list.begin(); it != delete_list.end();)
        {
            Task* tk = &*it++;
            DebugPrint(dbg_task, "task(%s) delete.", tk->DebugInfo());
            delete tk;
        }

    return epoll_n + c;
}