int AndroidClient::initJniEnv(JNIEnv* env, jobject objLstn) { m_env = env; m_pGarbage = new JObjGarbage(m_env, false); m_jobLstn = env->NewGlobalRef(objLstn); m_pGarbage->push(m_jobLstn); m_env->GetJavaVM(&m_jvm); m_jcLstn = m_env->FindClass(JNI_LISTENER_PATH); if (NULL == m_jcLstn) { SDK_LOG(LOG_LEVEL_ERROR, "handlePushMessageReq find class RTClistener failed!"); return GIM_JNI_ERROR; } m_pGarbage->push(m_jcLstn); m_hmidHandleMessage = m_env->GetMethodID(m_jcLstn, "handleMessage", "(Ljava/lang/String;)V"); if (NULL == m_hmidHandleMessage) { SDK_LOG(LOG_LEVEL_ERROR, "get jni method handleMessage fail!"); return GIM_JNI_ERROR; } return 0; }
int32 EventLoop::publish(const std::string& msg) { if (m_msgHandler) { SDK_LOG(LOG_LEVEL_TRACE, "EventLoop::publish"); m_msgHandler(m_MsgHandleCtx, msg); } }
CliConn* EventLoop::findConn(const std::string& cid) { SDK_LOG(LOG_LEVEL_TRACE, "EventLoop::findConn cid=%s", cid.c_str()) CliConnMap::iterator it = m_conns.find(cid); if (it != m_conns.end()) { return it->second; } return NULL; }
int32 EventLoop::delConn(const std::string& cid) { SDK_LOG(LOG_LEVEL_TRACE, "EventLoop::delConn cid=%s", cid.c_str()) CliConnMap::iterator it = m_conns.find(cid); if (it != m_conns.end()) { delete it->second; m_conns.erase(it); return 0; } return -1; }
CliConn* EventLoop::addConn(const std::string& cid) { SDK_LOG(LOG_LEVEL_TRACE, "EventLoop::addConn cid=%s", cid.c_str()) CliConn* conn = findConn(cid); if (conn) { return conn; } conn = new CliConn(this); std::pair<CliConnMap::iterator, bool> ret = m_conns.insert(CliConnMap::value_type(cid, conn)); m_conns[cid] = conn; return conn; }
int32 EventLoop::processOps() { SDK_LOG(LOG_LEVEL_TRACE, "EventLoop::processOps"); Op *op = NULL; char buf[1024]; int32 loop = sizeof(buf); while (m_ops.size()){ mutex_take(&m_ops_mtx); if (m_ops.size() >= (int32)sizeof(op)){ m_ops.read((uint8*)&op, sizeof(op)); mutex_give(&m_ops_mtx); } else{ mutex_give(&m_ops_mtx); break; } if (op) { SmartOp sp(op); sp->process(this); if (sp.release() > 0 && sp.get()) { CliConnMap::iterator it = m_conns.find(sp->getCid()); if (it != m_conns.end()) { CliConn* conn = it->second; conn->addTimer(sp->getSN(), sp); } } } } while (loop >= (int32)sizeof(buf)){ loop = recv(m_ctlfdr, buf, sizeof(buf), 0); } return 0; }
int32 EventLoop::run() { SDK_LOG(LOG_LEVEL_TRACE, "eventloop run"); const struct timeval c_tvmax = { LONG_MAX, LONG_MAX }; struct timeval tv; struct timeval* ptv; fd_set fds; while (m_run) { tv = c_tvmax; processTimers(tv); ptv = (tv_cmp(c_tvmax, tv) == 0) ? NULL : &tv; FD_ZERO(&fds); SOCKET maxfd = m_ctlfdr; FD_SET(m_ctlfdr, &fds); for (CliConnMap::iterator it = m_conns.begin(); it != m_conns.end();it++) { CliConn* pcon = it->second; if (pcon && pcon->getfd() != INVALID_SOCKET) { FD_SET(pcon->getfd(), &fds); maxfd = (maxfd >= pcon->getfd()) ? maxfd:pcon->getfd(); } } maxfd++; //SDK_LOG(LOG_LEVEL_TRACE, "select time out = %s", itostr(tv.tv_sec).c_str()); int32 ret = select(maxfd, &fds, NULL, NULL, ptv); if (ret < 0) { if (ret != /*SOCK_EINTR*/4) { SDK_LOG(LOG_LEVEL_TRACE, "select error %d", ret); return -1; } } else if (ret == 0) { //time out } else { if (FD_ISSET(m_ctlfdr, &fds)) { processOps(); } std::vector<std::string> errconns; for (CliConnMap::iterator it = m_conns.begin(); it != m_conns.end(); it++) { CliConn* pcon = it->second; if (pcon && FD_ISSET(pcon->getfd(), &fds)) { if (pcon->handleRead() < 0) { pcon->onDisconnect(true, MY_NETWORK_ERROR); errconns.push_back(pcon->getCid()); } } } for (std::vector<std::string>::iterator it = errconns.begin(); it != errconns.end(); ++it) { delConn(*it); } } } //onStopAndWait(); SDK_LOG(LOG_LEVEL_TRACE, "eventloop exit"); return 0; }