/** * Create Buffer. * * Note that 'format' is used from the client side to specify the DRI buffer * format, which could differ from the drawable format. For example, the * drawable could be 32b RGB, but the DRI buffer some YUV format (video) or * perhaps lower bit depth RGB (GL). The color conversion is handled when * blitting to front buffer, and page-flipping (overlay or flipchain) can * only be used if the display supports. */ static DRI2BufferPtr ARMSOCDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); struct ARMSOCDRI2BufferRec *buf = calloc(1, sizeof(*buf)); struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); struct armsoc_bo *bo; DEBUG_MSG("pDraw=%p, attachment=%d, format=%08x", pDraw, attachment, format); if (!buf) { ERROR_MSG("Couldn't allocate internal buffer structure"); return NULL; } buf->refcnt = 1; buf->previous_canflip = canflip(pDraw); DRIBUF(buf)->attachment = attachment; DRIBUF(buf)->cpp = pDraw->bitsPerPixel / 8; DRIBUF(buf)->format = format + 1; /* suppress DRI2 buffer reuse */ DRIBUF(buf)->flags = 0; /* If it is a pixmap, just migrate to a GEM buffer */ if (pDraw->type == DRAWABLE_PIXMAP) { if (!(bo = MigratePixmapToGEM(pARMSOC, pDraw))) { ErrorF("ARMSOCDRI2CreateBuffer: MigratePixmapToUMP failed\n"); free(buf); return NULL; } DRIBUF(buf)->pitch = armsoc_bo_pitch(bo); DRIBUF(buf)->name = armsoc_bo_name(bo); buf->bo = bo; return DRIBUF(buf); } /* We are not interested in anything other than back buffer requests ... */ if (attachment != DRI2BufferBackLeft || pDraw->type != DRAWABLE_WINDOW) { /* ... and just return some dummy UMP buffer */ bo = pARMSOC->scanout; DRIBUF(buf)->pitch = armsoc_bo_pitch(bo); DRIBUF(buf)->name = armsoc_bo_name(bo); buf->bo = bo; armsoc_bo_reference(bo); return DRIBUF(buf); } bo = armsoc_bo_from_drawable(pDraw); if (bo && armsoc_bo_width(bo) == pDraw->width && armsoc_bo_height(bo) == pDraw->height && armsoc_bo_bpp(bo) == pDraw->bitsPerPixel) { // Reuse existing DRIBUF(buf)->pitch = armsoc_bo_pitch(bo); DRIBUF(buf)->name = armsoc_bo_name(bo); buf->bo = bo; armsoc_bo_reference(bo); return DRIBUF(buf); } bo = armsoc_bo_new_with_dim(pARMSOC->dev, pDraw->width, pDraw->height, pDraw->depth, pDraw->bitsPerPixel, canflip(pDraw) ? ARMSOC_BO_SCANOUT : ARMSOC_BO_NON_SCANOUT); if (!bo) { ErrorF("ARMSOCDRI2CreateBuffer: BO alloc failed\n"); free(buf); return NULL; } armsoc_bo_set_drawable(bo, pDraw); DRIBUF(buf)->name = armsoc_bo_name(bo); DRIBUF(buf)->pitch = armsoc_bo_pitch(bo); buf->bo = bo; if (canflip(pDraw) && attachment != DRI2BufferFrontLeft) { /* Create an fb around this buffer. This will fail and we will * fall back to blitting if the display controller hardware * cannot scan out this buffer (for example, if it doesn't * support the format or there was insufficient scanout memory * at buffer creation time). */ int ret = armsoc_bo_add_fb(bo); if (ret) { WARNING_MSG( "Falling back to blitting a flippable window"); } } /* Register Pixmap as having a buffer that can be accessed externally, * so needs synchronised access */ // FIXME ARMSOCRegisterExternalAccess(pPixmap); return DRIBUF(buf); }
PacketReceiver::RecvState UDPPacketReceiver::checkSocketErrors(int len, bool expectingPacket) { if (len == 0) { /*SL_ELOG(fmt::format("PacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK (1)- {}\n", strerror( errno )));*/ /*this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK );*/ return RECV_STATE_CONTINUE; } #ifdef _WIN32 DWORD wsaErr = WSAGetLastError(); #endif //def _WIN32 if ( #ifdef _WIN32 wsaErr == WSAEWOULDBLOCK && !expectingPacket #else errno == EAGAIN && !expectingPacket #endif ) { return RECV_STATE_BREAK; } #ifdef unix if (errno == EAGAIN || errno == ECONNREFUSED || errno == EHOSTUNREACH) { Network::Address offender; if (pEndpoint_->getClosedPort(offender)) { // If we got a NO_SUCH_PORT error and there is an internal // channel to this address, mark it as remote failed. The logic // for dropping external channels that get NO_SUCH_PORT // exceptions is built into BaseApp::onClientNoSuchPort(). if (errno == ECONNREFUSED) { // 未实现 } this->dispatcher().errorReporter().reportException( REASON_NO_SUCH_PORT, offender); return RECV_STATE_CONTINUE; } else { WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "getClosedPort() failed\n"); } } #else if (wsaErr == WSAECONNRESET) { return RECV_STATE_CONTINUE; } #endif // unix #ifdef _WIN32 /*WARNING_MSG(fmt::format("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - {}\n", wsaErr));*/ #else WARNING_MSG(fmt::format("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - {}\n", kbe_strerror())); #endif /*this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK);*/ return RECV_STATE_CONTINUE; }
//------------------------------------------------------------------------------------- bool UDPPacketReceiver::checkSocketErrors(int len, bool expectingPacket) { if (len == 0) { WARNING_MSG( "PacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK (1)- %s\n", strerror( errno ) ); this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK ); return true; } #ifdef _WIN32 DWORD wsaErr = WSAGetLastError(); #endif //def _WIN32 if ( #ifdef _WIN32 wsaErr == WSAEWOULDBLOCK && !expectingPacket #else errno == EAGAIN && !expectingPacket #endif ) { return false; } #ifdef unix if (errno == EAGAIN || errno == ECONNREFUSED || errno == EHOSTUNREACH) { #if defined(PLAYSTATION3) this->dispatcher().errorReporter().reportException( REASON_NO_SUCH_PORT); return true; #else Mercury::Address offender; if (pEndpoint_->getClosedPort(offender)) { // If we got a NO_SUCH_PORT error and there is an internal // channel to this address, mark it as remote failed. The logic // for dropping external channels that get NO_SUCH_PORT // exceptions is built into BaseApp::onClientNoSuchPort(). if (errno == ECONNREFUSED) { // н╢й╣ож } this->dispatcher().errorReporter().reportException( REASON_NO_SUCH_PORT, offender); return true; } else { WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "getClosedPort() failed\n"); } #endif } #else if (wsaErr == WSAECONNRESET) { return true; } #endif // unix #ifdef _WIN32 WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - %d\n", wsaErr); #else WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - %s\n", kbe_strerror()); #endif this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK); return true; }
//------------------------------------------------------------------------------------- bool Componentbridge::findInterfaces() { int8 findComponentTypes[] = {UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE}; switch(componentType_) { case CELLAPP_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = RESOURCEMGR_TYPE; findComponentTypes[2] = DBMGR_TYPE; findComponentTypes[3] = CELLAPPMGR_TYPE; findComponentTypes[4] = BASEAPPMGR_TYPE; break; case BASEAPP_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = RESOURCEMGR_TYPE; findComponentTypes[2] = DBMGR_TYPE; findComponentTypes[3] = BASEAPPMGR_TYPE; findComponentTypes[4] = CELLAPPMGR_TYPE; break; case BASEAPPMGR_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = DBMGR_TYPE; findComponentTypes[2] = CELLAPPMGR_TYPE; break; case CELLAPPMGR_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = DBMGR_TYPE; findComponentTypes[2] = BASEAPPMGR_TYPE; break; case LOGINAPP_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = DBMGR_TYPE; findComponentTypes[2] = BASEAPPMGR_TYPE; break; case DBMGR_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; break; default: if(componentType_ != MESSAGELOG_TYPE && componentType_ != MACHINE_TYPE) findComponentTypes[0] = MESSAGELOG_TYPE; break; }; int ifind = 0; srand(KBEngine::getSystemTime()); uint16 nport = KBE_PORT_START + (rand() % 1000); while(findComponentTypes[ifind] != UNKNOWN_COMPONENT_TYPE) { if(dispatcher().isBreakProcessing()) return false; int8 findComponentType = findComponentTypes[ifind]; INFO_MSG("Componentbridge::process: finding %s...\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); Mercury::BundleBroadcast bhandler(networkInterface_, nport); if(!bhandler.good()) { KBEngine::sleep(10); nport = KBE_PORT_START + (rand() % 1000); continue; } if(bhandler.pCurrPacket() != NULL) { bhandler.pCurrPacket()->resetPacket(); } bhandler.newMessage(MachineInterface::onFindInterfaceAddr); MachineInterface::onFindInterfaceAddrArgs6::staticAddToBundle(bhandler, getUserUID(), getUsername(), componentType_, findComponentType, networkInterface_.intaddr().ip, bhandler.epListen().addr().port); if(!bhandler.broadcast()) { ERROR_MSG("Componentbridge::process: broadcast error!\n"); return false; } MachineInterface::onBroadcastInterfaceArgs8 args; if(bhandler.receive(&args, 0, 1000000)) { if(args.componentType == UNKNOWN_COMPONENT_TYPE) { //INFO_MSG("Componentbridge::process: not found %s, try again...\n", // COMPONENT_NAME_EX(findComponentType)); KBEngine::sleep(1000); // 如果是这些辅助组件没找到则跳过 if(findComponentType == MESSAGELOG_TYPE || findComponentType == RESOURCEMGR_TYPE) { WARNING_MSG("Componentbridge::process: not found %s!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); findComponentTypes[ifind] = -1; // 跳过标志 ifind++; } continue; } INFO_MSG("Componentbridge::process: found %s, addr:%s:%u\n", COMPONENT_NAME_EX((COMPONENT_TYPE)args.componentType), inet_ntoa((struct in_addr&)args.intaddr), ntohs(args.intaddr)); Componentbridge::getComponents().addComponent(args.uid, args.username.c_str(), (KBEngine::COMPONENT_TYPE)args.componentType, args.componentID, args.intaddr, args.intport, args.extaddr, args.extport); // 防止接收到的数据不是想要的数据 if(findComponentType == args.componentType) { ifind++; } else { ERROR_MSG("Componentbridge::process: %s not found. receive data is error!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); } } else { ERROR_MSG("Componentbridge::process: receive error!\n"); return false; } } ifind = 0; // 开始注册到所有的组件 while(findComponentTypes[ifind] != UNKNOWN_COMPONENT_TYPE) { if(dispatcher().isBreakProcessing()) return false; int8 findComponentType = findComponentTypes[ifind++]; if(findComponentType == -1) continue; INFO_MSG("Componentbridge::process: register self to %s...\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); if(getComponents().connectComponent(static_cast<COMPONENT_TYPE>(findComponentType), getUserUID(), 0) != 0) { ERROR_MSG("Componentbridge::register self to %s is error!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); dispatcher().breakProcessing(); return false; } } return true; }
static inline int createFile(void) { #ifdef _DEBUGFLAGS_H_ { static unsigned int registered = 0; if (unlikely(0 == registered)) { registered = 1; /* dirty work around to avoid deadlock: syslogex->register->syslogex */ registered = (registerLibraryDebugFlags(&debugFlags) == EXIT_SUCCESS); } } #endif /*_DEBUGFLAGS_H_*/ int error = pthread_mutex_lock(&fileLock); if (likely(EXIT_SUCCESS == error)) { int internalError = EXIT_SUCCESS; int flags = O_WRONLY|O_CREAT|O_TRUNC; if (likely((!(LogStat & LOG_FILE_WITHOUT_SYNC)) && (!(LogStat & LOG_FILE_SYNC_ON_ERRORS_ONLY)))) { flags |= O_SYNC; /* enable synchronous I/O to avoid data lost in case of crash */ } if (logFile != -1) { WARNING_MSG("logFile was NOT NULL"); if (close(logFile) != 0) { internalError = errno; ERROR_MSG("close %d error %d (%m)", logFile, internalError); } logFile = -1; } if (unlikely(NULL == processName)) { setProcessName(); } setFullFileName(); logFile = open(fullFileName,flags,S_IRUSR|S_IWUSR|S_IRGRP); if (likely(logFile != -1)) { fileSize = 0; if (LOG_FILE_DURATION & LogStat) { startTime = time(NULL); } } else { error = errno; ERROR_MSG("open %s for creation error %d (%m)", fullFileName, error); } internalError = pthread_mutex_unlock(&fileLock); if (internalError != EXIT_SUCCESS) { ERROR_MSG("pthread_mutex_lock fileLock error %d (%s)", internalError, strerror(internalError)); if (EXIT_SUCCESS == error) { error = internalError; } } } else { ERROR_MSG("pthread_mutex_lock fileLock error %d (%m)", error); } return error; }
//------------------------------------------------------------------------------------- void ClientApp::handleGameTick() { ++g_kbetime; threadPool_.onMainThreadTick(); networkInterface().processChannels(KBEngine::Network::MessageHandlers::pMainMessageHandlers); tickSend(); switch(state_) { case C_STATE_INIT: state_ = C_STATE_PLAY; break; case C_STATE_INITLOGINAPP_CHANNEL: state_ = C_STATE_PLAY; break; case C_STATE_LOGIN: state_ = C_STATE_PLAY; if(!ClientObjectBase::login()) { WARNING_MSG("ClientApp::handleGameTick: login is failed!\n"); return; } break; case C_STATE_LOGIN_BASEAPP_CHANNEL: { state_ = C_STATE_PLAY; bool ret = updateChannel(false, "", "", "", 0); if(ret) { // 先握手然后等helloCB之后再进行登录 Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::hello); (*pBundle) << KBEVersion::versionString(); (*pBundle) << KBEVersion::scriptVersionString(); if(Network::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Network::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); pServerChannel_->pFilter(NULL); } else { std::string key = ""; (*pBundle).appendBlob(key); } pServerChannel_->pEndPoint()->send(pBundle); Network::Bundle::ObjPool().reclaimObject(pBundle); // ret = ClientObjectBase::loginBaseapp(); } } break; case C_STATE_LOGIN_BASEAPP: state_ = C_STATE_PLAY; if(!ClientObjectBase::loginBaseapp()) { WARNING_MSG("ClientApp::handleGameTick: loginBaseapp is failed!\n"); return; } break; case C_STATE_PLAY: break; default: KBE_ASSERT(false); break; }; }
//------------------------------------------------------------------------------------- void ThreadPool::destroy() { isDestroyed_ = true; THREAD_MUTEX_LOCK(threadStateList_mutex_); DEBUG_MSG(fmt::format("ThreadPool::destroy(): starting size {0}.\n", allThreadList_.size())); THREAD_MUTEX_UNLOCK(threadStateList_mutex_); int itry = 0; while(true) { KBEngine::sleep(300); itry++; std::string taskaddrs = ""; THREAD_MUTEX_LOCK(threadStateList_mutex_); int count = (int)allThreadList_.size(); std::list<TPThread*>::iterator itr = allThreadList_.begin(); for(; itr != allThreadList_.end(); ++itr) { if((*itr)) { if((*itr)->state() != TPThread::THREAD_STATE_END) { (*itr)->sendCondSignal(); taskaddrs += (fmt::format("{0:p},", (void*)(*itr))); } else { count--; } } } THREAD_MUTEX_UNLOCK(threadStateList_mutex_); if(count <= 0) { break; } else { WARNING_MSG(fmt::format("ThreadPool::destroy(): waiting for thread({0})[{1}], try={2}\n", count, taskaddrs, itry)); } } THREAD_MUTEX_LOCK(threadStateList_mutex_); KBEngine::sleep(100); std::list<TPThread*>::iterator itr = allThreadList_.begin(); for(; itr != allThreadList_.end(); ++itr) { if((*itr)) { delete (*itr); (*itr) = NULL; } } allThreadList_.clear(); THREAD_MUTEX_UNLOCK(threadStateList_mutex_); THREAD_MUTEX_LOCK(finiTaskList_mutex_); if(finiTaskList_.size() > 0) { WARNING_MSG(fmt::format("ThreadPool::~ThreadPool(): Discarding {0} finished tasks.\n", finiTaskList_.size())); std::list<TPTask*>::iterator finiiter = finiTaskList_.begin(); for(; finiiter != finiTaskList_.end(); ++finiiter) { delete (*finiiter); } finiTaskList_.clear(); finiTaskList_count_ = 0; } THREAD_MUTEX_UNLOCK(finiTaskList_mutex_); THREAD_MUTEX_LOCK(bufferedTaskList_mutex_); if(bufferedTaskList_.size() > 0) { WARNING_MSG(fmt::format("ThreadPool::~ThreadPool(): Discarding {0} buffered tasks.\n", bufferedTaskList_.size())); while(bufferedTaskList_.size() > 0) { TPTask* tptask = bufferedTaskList_.front(); bufferedTaskList_.pop(); delete tptask; } } THREAD_MUTEX_UNLOCK(bufferedTaskList_mutex_); THREAD_MUTEX_DELETE(threadStateList_mutex_); THREAD_MUTEX_DELETE(bufferedTaskList_mutex_); THREAD_MUTEX_DELETE(finiTaskList_mutex_); DEBUG_MSG("ThreadPool::destroy(): successfully!\n"); }
//------------------------------------------------------------------------------------- bool KBEEmailVerificationTableRedis::resetpassword(DBInterface * pdbi, const std::string& name, const std::string& password, const std::string& code) { /* kbe_email_verification:code = hashes(accountName, type, datas, logtime) kbe_email_verification:accountName = code */ redisReply* pRedisReply = NULL; if (!pdbi->query(fmt::format("HMGET kbe_email_verification:{} accountName type, datas logtime", code), false)) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::bindEMail({}): cmd({}) is failed({})!\n", code, pdbi->lastquery(), pdbi->getstrerror())); } uint64 logtime = 1; int type = -1; std::string qname, qemail; if(pRedisReply) { if(pRedisReply->type == REDIS_REPLY_ARRAY) { if(RedisHelper::check_array_results(pRedisReply)) { qname = pRedisReply->element[0]->str; StringConv::str2value(type, pRedisReply->element[1]->str); qemail = pRedisReply->element[2]->str; StringConv::str2value(logtime, pRedisReply->element[3]->str); } } freeReplyObject(pRedisReply); } if(logtime > 0 && time(NULL) - logtime > g_kbeSrvConfig.emailResetPasswordInfo_.deadline) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::resetpassword({}): is expired! {} > {}.\n", code, (time(NULL) - logtime), g_kbeSrvConfig.emailResetPasswordInfo_.deadline)); return false; } if(qname.size() == 0 || password.size() == 0) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::resetpassword({}): name or password is NULL.\n", code)); return false; } if(qname != name) { WARNING_MSG(fmt::format("KBEEmailVerificationTableRedis::resetpassword: code({}) username({} != {}) not match.\n" , code, name, qname)); return false; } if((int)KBEEmailVerificationTable::V_TYPE_RESETPASSWORD != type) { ERROR_MSG(fmt::format("KBEEmailVerificationTableMysql::resetpassword({}): type({}) error!\n", code, type)); return false; } // 寻找dblog是否有此账号 KBEAccountTable* pTable = static_cast<KBEAccountTable*>(EntityTables::findByInterfaceName(pdbi->name()).findKBETable("kbe_accountinfos")); KBE_ASSERT(pTable); if(!pTable->updatePassword(pdbi, qname, KBE_MD5::getDigest(password.data(), password.length()))) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::resetpassword({}): update accountName({}) password error({})!\n", code, qname, pdbi->getstrerror())); return false; } delAccount(pdbi, (int8)V_TYPE_RESETPASSWORD, qname); return true; }
/** * Programme principal */ int main ( int argc, char *argv[] ) { /* exemples d'utilisation des macros du fichier notify.h */ INFO_MSG("Un message INFO_MSG : Debut du programme %s", argv[0]); /* macro INFO_MSG */ WARNING_MSG("Un message WARNING_MSG !"); /* macro INFO_MSG */ DEBUG_MSG("Un message DEBUG_MSG !"); /* macro DEBUG_MSG : uniquement si compil en mode DEBUG_MSG */ FILE *fp = NULL; /* le flux dans lequel les commandes seront lues : stdin (mode shell) ou un fichier */ if ( argc > 2 ) { usage_ERROR_MSG( argv[0] ); exit( EXIT_FAILURE ); } if(argc == 2 && strcmp(argv[1], "-h") == 0) { usage_ERROR_MSG( argv[0] ); exit( EXIT_SUCCESS ); } /*par defaut : mode shell interactif */ fp = stdin; if(argc == 2) { /* mode fichier de commandes */ fp = fopen( argv[1], "r" ); if ( fp == NULL ) { perror( "fopen" ); exit( EXIT_FAILURE ); } } /* boucle principale : lit puis execute une cmd en boucle */ while ( 1 ) { char input[MAX_STR]; if ( acquire_line( fp, input ) == 0 ) { /* Une nouvelle ligne a ete acquise dans le flux fp*/ int res = parse_and_execute_cmd_string(input); /* execution de la commande */ switch(res) { case CMD_OK_RETURN_VALUE: /* tout s'est bien passé */ break; case CMD_EMPTY_RETURN_VALUE: /* commande vide */ /* rien a faire ! */ break; case CMD_EXIT_RETURN_VALUE: /* sortie propre du programme */ if ( fp != stdin ) { fclose( fp ); } exit(EXIT_SUCCESS); break; default: /* erreur durant l'execution de la commande */ /* En mode "fichier" toute erreur implique la fin du programme ! */ if ( fp != stdin ) { fclose( fp ); /*macro ERROR_MSG : message d'erreur puis fin de programme ! */ ERROR_MSG("ERREUR DETECTEE. Aborts"); } break; } } if( fp != stdin && feof(fp) ) { /* mode fichier, fin de fichier => sortie propre du programme */ DEBUG_MSG("FIN DE FICHIER"); fclose( fp ); exit(EXIT_SUCCESS); } } /* tous les cas de sortie du programme sont gérés plus haut*/ ERROR_MSG("SHOULD NEVER BE HERE\n"); }
//------------------------------------------------------------------------------------- void ClientApp::handleGameTick() { g_kbetime++; threadPool_.onMainThreadTick(); handleTimers(); if(lastAddr.ip != 0) { getNetworkInterface().deregisterChannel(lastAddr); getNetworkInterface().registerChannel(pServerChannel_); lastAddr.ip = 0; } getNetworkInterface().processAllChannelPackets(KBEngine::Mercury::MessageHandlers::pMainMessageHandlers); tickSend(); switch(state_) { case C_STATE_INIT: state_ = C_STATE_PLAY; break; case C_STATE_INITLOGINAPP_CHANNEL: state_ = C_STATE_PLAY; break; case C_STATE_LOGIN: state_ = C_STATE_PLAY; if(!ClientObjectBase::login()) { WARNING_MSG("ClientApp::handleGameTick: login is failed!\n"); return; } break; case C_STATE_LOGIN_GATEWAY_CHANNEL: { state_ = C_STATE_PLAY; bool exist = false; if(pServerChannel_->endpoint()) { lastAddr = pServerChannel_->endpoint()->addr(); getNetworkInterface().dispatcher().deregisterFileDescriptor(*pServerChannel_->endpoint()); exist = getNetworkInterface().findChannel(pServerChannel_->endpoint()->addr()) != NULL; } bool ret = initBaseappChannel() != NULL; if(ret) { if(!exist) { getNetworkInterface().registerChannel(pServerChannel_); pTCPPacketReceiver_ = new Mercury::TCPPacketReceiver(*pServerChannel_->endpoint(), getNetworkInterface()); } else { pTCPPacketReceiver_->endpoint(pServerChannel_->endpoint()); } getNetworkInterface().dispatcher().registerFileDescriptor(*pServerChannel_->endpoint(), pTCPPacketReceiver_); // 先握手然后等helloCB之后再进行登录 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::hello); (*pBundle) << KBEVersion::versionString(); if(Mercury::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Mercury::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); pServerChannel_->pFilter(NULL); } else { std::string key = ""; (*pBundle).appendBlob(key); } pServerChannel_->pushBundle(pBundle); // ret = ClientObjectBase::loginGateWay(); } } break; case C_STATE_LOGIN_GATEWAY: state_ = C_STATE_PLAY; if(!ClientObjectBase::loginGateWay()) { WARNING_MSG("ClientApp::handleGameTick: loginGateWay is failed!\n"); return; } break; case C_STATE_PLAY: break; default: KBE_ASSERT(false); break; }; }
//------------------------------------------------------------------------------------- bool KBEEmailVerificationTableRedis::bindEMail(DBInterface * pdbi, const std::string& name, const std::string& code) { /* kbe_email_verification:code = hashes(accountName, type, datas, logtime) kbe_email_verification:accountName = code */ redisReply* pRedisReply = NULL; if (!pdbi->query(fmt::format("HMGET kbe_email_verification:{} accountName type, datas logtime", code), false)) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::bindEMail({}): cmd({}) is failed({})!\n", code, pdbi->lastquery(), pdbi->getstrerror())); } uint64 logtime = 1; int type = -1; std::string qname, qemail; if(pRedisReply) { if(pRedisReply->type == REDIS_REPLY_ARRAY) { if(RedisHelper::check_array_results(pRedisReply)) { qname = pRedisReply->element[0]->str; StringConv::str2value(type, pRedisReply->element[1]->str); qemail = pRedisReply->element[2]->str; StringConv::str2value(logtime, pRedisReply->element[3]->str); } } freeReplyObject(pRedisReply); } if(logtime > 0 && time(NULL) - logtime > g_kbeSrvConfig.emailBindInfo_.deadline) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::bindEMail({}): is expired! {} > {}.\n", code, (time(NULL) - logtime), g_kbeSrvConfig.emailBindInfo_.deadline)); return false; } if(qname.size() == 0 || qemail.size() == 0) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::bindEMail({}): name or email is NULL.\n", code)); return false; } if(qemail != name) { WARNING_MSG(fmt::format("KBEEmailVerificationTableRedis::bindEMail: code({}) username({}:{}, {}) not match.\n" , code, name, qname, qemail)); return false; } if((int)KBEEmailVerificationTable::V_TYPE_BIND_MAIL != type) { ERROR_MSG(fmt::format("KBEEmailVerificationTableMysql::bindEMail({}): type({}) error!\n", code, type)); return false; } /* kbe_accountinfos:accountName = hashes(password, bindata, email, entityDBID, flags, deadline, regtime, lasttime, numlogin) */ // 如果查询失败则返回存在, 避免可能产生的错误 if(!pdbi->query(fmt::format("HSET kbe_accountinfos:{} email {}", qname, qemail), false)) { ERROR_MSG(fmt::format("KBEEmailVerificationTableRedis::bindEMail({}): update kbe_accountinfos({}) error({})!\n", code, qname, pdbi->getstrerror())); return false; } delAccount(pdbi, (int8)V_TYPE_BIND_MAIL, name); return true; }
mem init_mem( uint32_t nseg ) { mem vm = calloc( nseg+3, sizeof( *vm ) ); if ( NULL == vm ) { WARNING_MSG( "Unable to allocate host memory for vmem" ); return NULL; } else { uint i; vm->seg = calloc( nseg+2, sizeof( *(vm->seg) ) ); if ( NULL == vm->seg ) { WARNING_MSG( "Unable to allocate host memory for vmem segment" ); free( vm ); return NULL; } // each segment is initialised to a null value // Note that though this is unnecessary since a calloc is used // this permits future evolution of the default initialisation values for ( i= 0; i< nseg; i++ ) { vm->seg[i].name = NULL; vm->seg[i].content = NULL; vm->seg[i].start._64 = 0x0; vm->seg[i].size._64 = 0x0; vm->seg[i].attr = 0x0; } /* //Definition de lib vm->seg[i].name=calloc(5, sizeof(int)); strcpy(vm->seg[i].name,"[lib]"); vm->seg[i].start._32 = 0xFF7FD000; vm->seg[i].size._32 = 0x00002000; vm->seg[i].content = calloc(1, vm->seg[i].size._64); vm->seg[i].attr = 0x00002002; //32 bit RW i++; */ //Definition de stack vm->seg[i].name=calloc(7, sizeof(int)); strcpy(vm->seg[i].name,"[stack]"); vm->seg[i].start._64 = 0xFF7FF000; vm->seg[i].size._64 = 0x00800000; vm->seg[i].content = calloc(1, vm->seg[i].size._64); vm->seg[i].attr = 0x00002002; i++; //Definition de vsyscall vm->seg[i].name=calloc(10, sizeof(int)); strcpy(vm->seg[i].name,"[vsyscall]"); vm->seg[i].start._64 = 0xFFFFF000; vm->seg[i].size._64 = 0x00000FFF; vm->seg[i].content = calloc(1, vm->seg[i].size._64); vm->seg[i].attr = 0x00002003; //32 bits r-x i++; vm->nseg = nseg+2; } return vm; }
/** * @param fp le fichier elf original * @param seg le segment à reloger * @param mem l'ensemble des segments * @param endianness le boutisme du programme * @param symtab la table des symbole du programme * * @brief Cette fonction effectue la relocation du segment passé en parametres * @brief l'ensemble des segments doit déjà avoir été chargé en memoire. * */ void reloc_segment(FILE* fp, segment seg, char* segname, memory mem, unsigned int endianness,stab* symtab) { byte *ehdr = __elf_get_ehdr(fp); uint32_t scnsz = 0; Elf32_Rel *rel = NULL; char* reloc_name = malloc(strlen(segname)+strlen(RELOC_PREFIX_STR)+1); scntab section_tab; // on recompose le nom de la section memcpy(reloc_name,RELOC_PREFIX_STR,strlen(RELOC_PREFIX_STR)+1); strcat(reloc_name,segname); // on récupere le tableau de relocation et la table des sections rel = (Elf32_Rel *)elf_extract_scn_by_name( ehdr, fp, reloc_name, &scnsz, NULL ); elf_load_scntab(fp ,32, §ion_tab); if (rel != NULL && seg.raddr!=NULL && seg.size !=0) { INFO_MSG("--------------Relocation de %s-------------------\n",segname) ; INFO_MSG("Nombre de symboles a reloger: %ld\n",scnsz/sizeof(*rel)) ; int i = 0, j = 0; unsigned int V = 0; unsigned int S = 0; unsigned int A = 0; unsigned int T = 0; for (i=0; i<scnsz/sizeof(*rel); i++) { T =0; __Elf_Rel_flip_endianness((byte *)(rel+i), 32, endianness); unsigned int offset = rel[i].r_offset; // decalage par rapport au debut de section int sym = (int) ELF32_R_SYM(rel[i].r_info); int type = (unsigned char) ELF32_R_TYPE(rel[i].r_info); int P = seg.vaddr + offset; DEBUG_MSG("Entrée de relocation : offset %08x info =%08x sym = %08x type =%08x\n",rel[i].r_offset,rel[i].r_info,sym,type); DEBUG_MSG("Symbole en fonction duquel on reloge : symbole %s de type %d\n",symtab->sym[sym].name, type); if (symtab->sym[sym].type==STT_SECTION) { S = symtab->sym[sym].addr._32; if (type == R_ARM_ABS8) { uint8_t oct = read_memory_value(P, mem); if (oct < 0) A = oct | 0xFFFFFF00; else A = oct; V = A + S; write_memory_value(P, V, mem); printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V); } if (type == R_ARM_ABS32) { A = read_word(P, mem) ; V = (S + A) | T; printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V); write_word(P, V, mem); } if (type == R_ARM_THM_CALL) { } } else if (symtab->sym[sym].type==STT_FUNC) { T = 1; S = symtab->sym[sym].addr._32; if (type == R_ARM_ABS8) { A = read_memory_value(P, mem) ; V = A + S; printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V); write_memory_value(P, V, mem); } if (type == R_ARM_ABS32) { A = read_word(P, mem) << 1; V = (S + A) | T; printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V); write_word(P, V, mem); } if (type == R_ARM_THM_CALL) { } } else if (symtab->sym[sym].type==STT_NOTYPE) { S = symtab->sym[sym].addr._32; if (type == R_ARM_ABS8) { A = read_memory_value(P, mem); V = A + S; printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V); write_memory_value(P, V, mem); } if (type == R_ARM_ABS32) { A = read_word(P, mem); V = (S + A) | T; printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V); write_word(P, V, mem); } if (type == R_ARM_THM_CALL) { } } else { WARNING_MSG("%d non traité pour l'instant",symtab->sym[sym].type) ; continue; } } } del_scntab(section_tab); free( rel ); free( reloc_name ); free( ehdr ); }
//------------------------------------------------------------------------------------- void Channel::processPackets(KBEngine::Network::MessageHandlers* pMsgHandlers) { lastTickBytesReceived_ = 0; if(pMsgHandlers_ != NULL) { pMsgHandlers = pMsgHandlers_; } if (this->isDestroyed()) { ERROR_MSG(fmt::format("Channel::processPackets({}): channel[{:p}] is destroyed.\n", this->c_str(), (void*)this)); return; } if(this->isCondemn()) { ERROR_MSG(fmt::format("Channel::processPackets({}): channel[{:p}] is condemn.\n", this->c_str(), (void*)this)); //this->destroy(); return; } if(pPacketReader_ == NULL) { handshake(); } uint8 idx = bufferedReceivesIdx_; bufferedReceivesIdx_ = 1 - bufferedReceivesIdx_; try { BufferedReceives::iterator packetIter = bufferedReceives_[idx].begin(); for(; packetIter != bufferedReceives_[idx].end(); packetIter++) { Packet* pPacket = (*packetIter); pPacketReader_->processMessages(pMsgHandlers, pPacket); if(pPacket->isTCPPacket()) TCPPacket::ObjPool().reclaimObject(static_cast<TCPPacket*>(pPacket)); else UDPPacket::ObjPool().reclaimObject(static_cast<UDPPacket*>(pPacket)); } }catch(MemoryStreamException &) { Network::MessageHandler* pMsgHandler = pMsgHandlers->find(pPacketReader_->currMsgID()); WARNING_MSG(fmt::format("Channel::processPackets({}): packet invalid. currMsg=(name={}, id={}, len={}), currMsgLen={}\n", this->c_str() , (pMsgHandler == NULL ? "unknown" : pMsgHandler->name) , pPacketReader_->currMsgID() , (pMsgHandler == NULL ? -1 : pMsgHandler->msgLen) , pPacketReader_->currMsgLen())); pPacketReader_->currMsgID(0); pPacketReader_->currMsgLen(0); condemn(); } bufferedReceives_[idx].clear(); this->send(); }
int InternalDatabaseReader::getQueryResults(CorbaClientAdaptor &adaptor) { int error(EXIT_SUCCESS); MutexMgr mutexMgr(mutex); const unsigned int numberOfColumns(sqlite3_column_count(SQLQueryStatement)); adaptor.setNumberOfSubItems(numberOfColumns); // set Labels'name corresponding to the current query'fields for(unsigned int i=0;i<numberOfColumns;i++) { const char *label = sqlite3_column_name(SQLQueryStatement,i); DEBUG_MSG("label %u = %s",i,label); adaptor.setLabel(i,label); } // retrieve the result of the current query unsigned int row(0); std::string errorMsg; unsigned int nbRetries(0); do { error = sqlite3_step(SQLQueryStatement); DEBUG_VAR(error,"%d"); switch(error) { case SQLITE_DONE: DEBUG_MSG("SQLITE_DONE"); break; case SQLITE_ROW: { for(unsigned int column=0;column<numberOfColumns;column++) { const int cellDataType = sqlite3_column_type(SQLQueryStatement,column); DEBUG_VAR(cellDataType,"%d"); switch(cellDataType) { case SQLITE_INTEGER: { const int value = sqlite3_column_int(SQLQueryStatement,column); DEBUG_VAR(value,"%d"); adaptor.setValue(row,column,value); } break; case SQLITE_FLOAT: { const double value = sqlite3_column_double(SQLQueryStatement,column); DEBUG_VAR(value,"%f"); adaptor.setValue(row,column,value); } break; case SQLITE_TEXT: { const char *value = (char *)sqlite3_column_text(SQLQueryStatement,column); DEBUG_VAR(value,"%s"); adaptor.setValue(row,column,value); } break; case SQLITE_BLOB: NOTICE_MSG("BLOB (not yet supported)"); break; case SQLITE_NULL: DEBUG_MSG("NULL"); // do Nothing break; } //switch(cellDataType) } //for(unsigned int column=0;column<numberOfColumns;column++) } //case SQLITE_ROW break; case SQLITE_BUSY: DEBUG_MSG("SQLITE_BUSY"); nbRetries++; WARNING_MSG("error during query execution, database is lock, retrying...(%u)",nbRetries); break; case SQLITE_ERROR: { const char *msg = sqlite3_errmsg(database); ERROR_MSG("SQLITE_ERROR %s",msg); errorMsg = msg; } break; case SQLITE_MISUSE: { const char *msg = sqlite3_errmsg(database); ERROR_MSG("SQLITE_MISUSE %s",msg); errorMsg = msg; } break; default: { const char *msg = sqlite3_errmsg(database); ERROR_MSG("SQLite return code %d, %s",msg); errorMsg = msg; } break; } // switch(error) ++row; DEBUG_MSG("new line (%u)",row); } while((SQLITE_ROW == error) || ((SQLITE_BUSY == error) && (nbRetries < NB_MAX_RETRIES))); sqlite3_reset(SQLQueryStatement); if (error != SQLITE_DONE) { throw exception(error,errorMsg); } return error; }
//------------------------------------------------------------------------------------- void DebugHelper::sync() { if(bufferedLogPackets_.size() == 0) return; if(messagelogAddr_.isNone()) { if(bufferedLogPackets_.size() > 128) { ERROR_MSG("DebugHelper::sync: can't found messagelog. packet size=%u.\n", bufferedLogPackets_.size()); clearBufferedLog(); } return; } int8 v = Mercury::g_trace_packet; Mercury::g_trace_packet = 0; Mercury::Channel* pChannel = pNetworkInterface_->findChannel(messagelogAddr_); if(pChannel == NULL) { if(bufferedLogPackets_.size() > 1024) { messagelogAddr_.ip = 0; messagelogAddr_.port = 0; WARNING_MSG("DebugHelper::sync: is no use the messagelog, packet size=%u.\n", bufferedLogPackets_.size()); clearBufferedLog(); } Mercury::g_trace_packet = v; return; } if(bufferedLogPackets_.size() > 0) { if(bufferedLogPackets_.size() > 32) { WARNING_MSG("DebugHelper::sync: packet size=%u.\n", bufferedLogPackets_.size()); } int i = 0; size_t totalLen = 0; std::list< Mercury::Bundle* >::iterator iter = bufferedLogPackets_.begin(); for(; iter != bufferedLogPackets_.end();) { if(i++ >= 32 || totalLen > (PACKET_MAX_SIZE_TCP * 10)) break; totalLen += (*iter)->currMsgLength(); pChannel->send((*iter)); Mercury::Bundle::ObjPool().reclaimObject((*iter)); bufferedLogPackets_.erase(iter++); } } Mercury::g_trace_packet = v; }
inline int InternalDatabaseReader::openDatabase(const char *fileName) { int error(EXIT_SUCCESS); error = sqlite3_open(fileName,&database); if (0 == error) { char *errorMsg = NULL; // the configuration of the database has already be done // by the writer but it seems that the reader must set the same parameters // to avoid to lock the database (or at least some of them) (?). error = sqlite3_exec(database, "PRAGMA synchronous = OFF", NULL, NULL, &errorMsg); if (unlikely(error != SQLITE_OK)) { //std::string exceptionMsg; WARNING_MSG("error setting asynchronous mode %d (%s)",error,errorMsg); //sprintf(exceptionMsg,"error during database creation: error setting asynchronous mode (%s)",errorMsg); sqlite3_free(errorMsg); //throw exception(error,exceptionMsg); } error = sqlite3_exec(database, "PRAGMA journal_mode = "SQLITE_JOURNAL_MODE, NULL, NULL, &errorMsg); if (unlikely(error != SQLITE_OK)) { //std::string exceptionMsg; WARNING_MSG("error setting journal mode to " SQLITE_JOURNAL_MODE " %d (%s)",error,errorMsg); //sprintf(exceptionMsg,"error during database creation: error setting journal mode to memory (%s)",errorMsg); sqlite3_free(errorMsg); //throw exception(error,exceptionMsg); } error = sqlite3_exec(database, "PRAGMA foreign_key = ON", NULL, NULL, &errorMsg); if (unlikely(error != SQLITE_OK)) { //std::string exceptionMsg; WARNING_MSG("error setting foreign key on %d (%s)",error,errorMsg); //sprintf(exceptionMsg,"error during database creation: error setting foreign key on (%s)",errorMsg); sqlite3_free(errorMsg); //throw exception(error,exceptionMsg); } // just add the public interface: the helpers view to use data received by the AIS // and the default query view //const char *tail = NULL; const char *SQLQueries[] = { "create temporary view Last_Positions as SELECT MMSI ,latitude ,longitude ,navigationStatus ,rateOfTurn ,speedOverGround ,positionAccuracy ,courseOverGround ,trueHeading ,specialManoeuvreIndicator , DATE FROM TRAVELS_POSITIONS INNER JOIN(SELECT MMSI AS M ,MAX(DATE) AS D FROM TRAVELS_POSITIONS GROUP BY mmsi) L ON (MMSI = L.M AND DATE = L.D)" ,"create temporary view Current_AIS_Map as" " select VESSELS.name AS name, VESSELS.callSign AS callsign, VESSELS.type AS type, VESSELS.MMSI AS mmsi, VESSELS.IMONumber AS IMONumber, REF_COUNTRIES.Country AS Country," "REF_TYPE_OF_ELECTRONIC_POSITION_FIXING_DEVICE.DeviceType AS PosDeviceType, VESSELS.dimension_A AS dimension_A," "VESSELS.dimension_B AS dimension_B, VESSELS.dimension_C AS dimension_C, VESSELS.dimension_D AS dimension_D, VESSELS.draught AS draught," "VESSELS.CreationTime AS CreationTime, TRAVELS.destination AS destination, TRAVELS.ETA AS ETA, Last_Positions.latitude AS latitude," "Last_Positions.longitude AS longitude, Last_Positions.navigationStatus AS navigationStatus, Last_Positions.rateOfTurn AS rateOfTurn," "Last_Positions.specialManoeuvreIndicator, Last_Positions.trueHeading, Last_Positions.courseOverGround, Last_Positions.positionAccuracy," "Last_Positions.speedOverGround, Last_Positions.[date], VESSELS.lastUpdateTime" " FROM VESSELS INNER JOIN REF_TYPE_OF_ELECTRONIC_POSITION_FIXING_DEVICE ON VESSELS.typeOfPositionDevice = REF_TYPE_OF_ELECTRONIC_POSITION_FIXING_DEVICE.id INNER JOIN REF_COUNTRIES ON VESSELS.country = REF_COUNTRIES.id INNER JOIN TRAVELS ON VESSELS.MMSI = TRAVELS.MMSI INNER JOIN Last_Positions ON VESSELS.MMSI = Last_Positions.MMSI" " ORDER BY Last_Positions.[date]" }; register unsigned int nbQueries(sizeof(SQLQueries)/sizeof(SQLQueries[0])); register const char **SQLQuery = SQLQueries; error = SQLITE_OK; unsigned int nbRetries(0); while ((nbQueries >0) && (SQLITE_OK == error) && (nbRetries < NB_MAX_RETRIES)) { error = sqlite3_exec(database,*SQLQuery,NULL,NULL,&errorMsg); if (likely(SQLITE_OK == error)) { SQLQuery++; nbQueries--; nbRetries = 0; } else { if (SQLITE_BUSY == error) { nbRetries++; WARNING_MSG("error during view creation, database is lock, retrying...(%u)",nbRetries); } else { std::string exceptionMsg; ERROR_MSG("error during view creation,%s error %d (%s)",*SQLQuery,error,errorMsg); sprintf(exceptionMsg,"error during view creation by request %s (%s)",*SQLQuery,errorMsg); sqlite3_free(errorMsg); throw exception(error,exceptionMsg); } } } // while ((nbQueries >0) && (SQLITE_OK == error)) } else { std::string exceptionMsg; ERROR_MSG("error opening database %s, sqlite3_open error %d",fileName,error); sprintf(exceptionMsg,"error opening database %s, sqlite3_open error %d",fileName,error); throw exception(error,exceptionMsg); } return error; }
/** * This method should be called to handle requests on the socket. */ bool WatcherNub::receiveRequest() { if (!isInitialised_) { // TODO: Allow calls to this when not initialised before the client // currently does this. Should really fix the client so that this is // only called once initialised. return false; } sockaddr_in senderAddr; int len; if (wrh_ == NULL) { ERROR_MSG( "WatcherNub::receiveRequest: Can't call me before\n" "\tcalling setRequestHandler(WatcherRequestHandler*)\n" ); return false; } if (insideReceiveRequest_) { ERROR_MSG( "WatcherNub::receiveRequest: BAD THING NOTICED:\n" "\tAttempted re-entrant call to receiveRequest\n" ); return false; } insideReceiveRequest_ = true; // try to recv len = socket_.recvfrom( requestPacket_, WN_PACKET_SIZE, senderAddr ); if (len == -1) { // EAGAIN = no packets waiting, ECONNREFUSED = rejected outgoing packet #ifdef _WIN32 int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK && err != WSAECONNREFUSED && err != WSAECONNRESET) #else int err = errno; if (err != EAGAIN && err != ECONNREFUSED) #endif { ERROR_MSG( "WatcherNub::receiveRequest: recvfrom failed\n" ); } insideReceiveRequest_ = false; return false; } // make sure we haven't picked up a weird packet (from when broadcast // was on, say ... hey, it could happen!) WatcherDataMsg * wdm = (WatcherDataMsg*)requestPacket_; if (len < (int)sizeof(WatcherDataMsg)) { ERROR_MSG( "WatcherNub::receiveRequest: Packet is too short\n" ); insideReceiveRequest_ = false; return false; } if (! (wdm->message == WATCHER_MSG_GET || wdm->message == WATCHER_MSG_GET_WITH_DESC || wdm->message == WATCHER_MSG_SET || wdm->message == WATCHER_MSG_GET2 || wdm->message == WATCHER_MSG_SET2 ) ) { wrh_->processExtensionMessage( wdm->message, requestPacket_ + sizeof( wdm->message ), len - sizeof( wdm->message ), Mercury::Address( senderAddr.sin_addr.s_addr, senderAddr.sin_port ) ); insideReceiveRequest_ = false; return true; } // Our reply handler for the current request. WatcherPacketHandler *packetHandler = NULL; // and call back to the program switch (wdm->message) { case WATCHER_MSG_GET: case WATCHER_MSG_GET_WITH_DESC: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_1, false ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { wrh_->processWatcherGetRequest( *packetHandler, astr, (wdm->message == WATCHER_MSG_GET_WITH_DESC) ); astr += strlen(astr)+1; } } break; case WATCHER_MSG_GET2: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_2, false ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { unsigned int & seqNum = (unsigned int &)*astr; astr += sizeof(unsigned int); wrh_->processWatcherGet2Request( *packetHandler, astr, seqNum ); astr += strlen(astr)+1; } } break; case WATCHER_MSG_SET: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_1, true ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { char *bstr = astr + strlen(astr)+1; wrh_->processWatcherSetRequest( *packetHandler, astr,bstr ); astr = bstr + strlen(bstr)+1; } } break; case WATCHER_MSG_SET2: { // Create the packet reply handler for the current incoming request packetHandler = new WatcherPacketHandler( socket_, senderAddr, wdm->count, WatcherPacketHandler::WP_VERSION_2, true ); char *astr = wdm->string; for(int i=0;i<wdm->count;i++) { wrh_->processWatcherSet2Request( *packetHandler, astr ); } } break; default: { Mercury::Address srcAddr( senderAddr.sin_addr.s_addr, senderAddr.sin_port ); WARNING_MSG( "WatcherNub::receiveRequest: " "Unknown message %d from %s\n", wdm->message, srcAddr.c_str() ); } break; } // Start running the packet handler now, it will delete itself when // complete. if (packetHandler) { packetHandler->run(); packetHandler = NULL; } // and we're done! insideReceiveRequest_ = false; return true; }
//------------------------------------------------------------------------------------- void Base::addPersistentsDataToStream(uint32 flags, MemoryStream* s) { std::vector<ENTITY_PROPERTY_UID> log; // 再将base中存储属性取出 PyObject* pydict = PyObject_GetAttrString(this, "__dict__"); // 先将celldata中的存储属性取出 ScriptDefModule::PROPERTYDESCRIPTION_MAP& propertyDescrs = pScriptModule_->getPersistentPropertyDescriptions(); ScriptDefModule::PROPERTYDESCRIPTION_MAP::const_iterator iter = propertyDescrs.begin(); if(pScriptModule_->hasCell()) { addPositionAndDirectionToStream(*s); } for(; iter != propertyDescrs.end(); ++iter) { PropertyDescription* propertyDescription = iter->second; std::vector<ENTITY_PROPERTY_UID>::const_iterator finditer = std::find(log.begin(), log.end(), propertyDescription->getUType()); if(finditer != log.end()) continue; const char* attrname = propertyDescription->getName(); if(propertyDescription->isPersistent() && (flags & propertyDescription->getFlags()) > 0) { PyObject *key = PyUnicode_FromString(attrname); if(cellDataDict_ != NULL && PyDict_Contains(cellDataDict_, key) > 0) { PyObject* pyVal = PyDict_GetItemString(cellDataDict_, attrname); if(!propertyDescription->getDataType()->isSameType(pyVal)) { CRITICAL_MSG(fmt::format("{}::addPersistentsDataToStream: {} persistent({}) type(curr_py: {} != {}) error.\n", this->scriptName(), this->id(), attrname, (pyVal ? pyVal->ob_type->tp_name : "unknown"), propertyDescription->getDataType()->getName())); } else { (*s) << propertyDescription->getUType(); log.push_back(propertyDescription->getUType()); propertyDescription->addPersistentToStream(s, pyVal); DEBUG_PERSISTENT_PROPERTY("addCellPersistentsDataToStream", attrname); } } else if(PyDict_Contains(pydict, key) > 0) { PyObject* pyVal = PyDict_GetItem(pydict, key); if(!propertyDescription->getDataType()->isSameType(pyVal)) { CRITICAL_MSG(fmt::format("{}::addPersistentsDataToStream: {} persistent({}) type(curr_py: {} != {}) error.\n", this->scriptName(), this->id(), attrname, (pyVal ? pyVal->ob_type->tp_name : "unknown"), propertyDescription->getDataType()->getName())); } else { (*s) << propertyDescription->getUType(); log.push_back(propertyDescription->getUType()); propertyDescription->addPersistentToStream(s, pyVal); DEBUG_PERSISTENT_PROPERTY("addBasePersistentsDataToStream", attrname); } } else { WARNING_MSG(fmt::format("{}::addPersistentsDataToStream: {} not found Persistent({}), use default values!\n", this->scriptName(), this->id(), attrname)); (*s) << propertyDescription->getUType(); log.push_back(propertyDescription->getUType()); propertyDescription->addPersistentToStream(s, NULL); } Py_DECREF(key); } SCRIPT_ERROR_CHECK(); } Py_XDECREF(pydict); SCRIPT_ERROR_CHECK(); }
/** * This method initialises the watcher nub. */ bool WatcherNub::init( const char * listeningInterface, uint16 listeningPort ) { //INFO_MSG( "WatcherNub::init: listeningInterface = '%s', listeningPort = " // "%hd\n", listeningInterface ? listeningInterface : "", listeningPort ); if (isInitialised_) { // WARNING_MSG( "WatcherNub::init: Already initialised.\n" ); return true; } isInitialised_ = true; // open the socket socket_.socket(SOCK_DGRAM); if(!socket_.good()) { ERROR_MSG( "WatcherNub::init: socket() failed\n" ); return false; } if (socket_.setnonblocking(true)) // make it nonblocking { ERROR_MSG( "WatcherNub::init: fcntl(O_NONBLOCK) failed\n" ); return false; } u_int32_t ifaddr = INADDR_ANY; #ifndef _WIN32 // If the interface resolves to an address, use that instead of // searching for a matching interface. if (inet_aton( listeningInterface, (struct in_addr *)&ifaddr ) == 0) #endif { // ask endpoint to parse the interface specification into a name char ifname[IFNAMSIZ]; bool listeningInterfaceEmpty = (listeningInterface == NULL || listeningInterface[0] == 0); if (socket_.findIndicatedInterface( listeningInterface, ifname ) == 0) { //INFO_MSG( "WatcherNub::init: creating on interface '%s' (= %s)\n", // listeningInterface, ifname ); if (socket_.getInterfaceAddress( ifname, ifaddr ) != 0) { WARNING_MSG( "WatcherNub::init: couldn't get addr of interface %s " "so using all interfaces\n", ifname ); } } else if (!listeningInterfaceEmpty) { WARNING_MSG( "WatcherNub::init: couldn't parse interface spec %s " "so using all interfaces\n", listeningInterface ); } } if (socket_.bind( listeningPort, ifaddr )) { ERROR_MSG( "WatcherNub::init: bind() failed\n" ); socket_.close(); return false; } return true; }
void* TPThread::threadFunc(void* arg) #endif { TPThread * tptd = static_cast<TPThread*>(arg); ThreadPool* pThreadPool = tptd->threadPool(); bool isRun = true; tptd->reset_done_tasks(); #if KBE_PLATFORM == PLATFORM_WIN32 #else pthread_detach(pthread_self()); #endif tptd->onStart(); while(isRun) { if(tptd->task() != NULL) { isRun = true; } else { tptd->reset_done_tasks(); isRun = tptd->onWaitCondSignal(); } if(!isRun || pThreadPool->isDestroyed()) { if(!pThreadPool->hasThread(tptd)) tptd = NULL; goto __THREAD_END__; } TPTask * task = tptd->task(); if(task == NULL) continue; tptd->state_ = THREAD_STATE_BUSY; while(task && !tptd->threadPool()->isDestroyed()) { tptd->inc_done_tasks(); tptd->onProcessTaskStart(task); tptd->processTask(task); tptd->onProcessTaskEnd(task); // 尝试继续从任务队列里取出一个繁忙的未处理的任务 TPTask * task1 = tptd->tryGetTask(); if(!task1) { tptd->onTaskCompleted(); break; } else { pThreadPool->addFiniTask(task); task = task1; tptd->task(task1); } } } __THREAD_END__: if(tptd) { TPTask * task = tptd->task(); if(task) { WARNING_MSG(fmt::format("TPThread::threadFunc: task {0:p} not finish, thread.{1:p} will exit.\n", (void*)task, (void*)tptd)); delete task; } tptd->onEnd(); tptd->state_ = THREAD_STATE_END; tptd->reset_done_tasks(); } #if KBE_PLATFORM == PLATFORM_WIN32 return 0; #else pthread_exit(NULL); return NULL; #endif }
//------------------------------------------------------------------------------------- bool Componentbridge::findInterfaces() { if(state_ == 1) { srand(KBEngine::getSystemTime()); uint16 nport = KBE_PORT_START + (rand() % 1000); while(findComponentTypes_[findIdx_] != UNKNOWN_COMPONENT_TYPE) { if(dispatcher().isBreakProcessing()) return false; int8 findComponentType = findComponentTypes_[findIdx_]; INFO_MSG("Componentbridge::process: finding %s...\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); Mercury::BundleBroadcast bhandler(networkInterface_, nport); if(!bhandler.good()) { return false; } bhandler.itry(0); if(bhandler.pCurrPacket() != NULL) { bhandler.pCurrPacket()->resetPacket(); } bhandler.newMessage(MachineInterface::onFindInterfaceAddr); MachineInterface::onFindInterfaceAddrArgs6::staticAddToBundle(bhandler, getUserUID(), getUsername(), componentType_, findComponentType, networkInterface_.intaddr().ip, bhandler.epListen().addr().port); if(!bhandler.broadcast()) { ERROR_MSG("Componentbridge::process: broadcast error!\n"); return false; } MachineInterface::onBroadcastInterfaceArgs8 args; if(bhandler.receive(&args, 0, 10000000)) { if(args.componentType == UNKNOWN_COMPONENT_TYPE) { //INFO_MSG("Componentbridge::process: not found %s, try again...\n", // COMPONENT_NAME_EX(findComponentType)); // 如果是这些辅助组件没找到则跳过 if(findComponentType == MESSAGELOG_TYPE || findComponentType == RESOURCEMGR_TYPE) { WARNING_MSG("Componentbridge::process: not found %s!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); findComponentTypes_[findIdx_] = -1; // 跳过标志 findIdx_++; } return false; } INFO_MSG("Componentbridge::process: found %s, addr:%s:%u\n", COMPONENT_NAME_EX((COMPONENT_TYPE)args.componentType), inet_ntoa((struct in_addr&)args.intaddr), ntohs(args.intaddr)); Componentbridge::getComponents().addComponent(args.uid, args.username.c_str(), (KBEngine::COMPONENT_TYPE)args.componentType, args.componentID, args.intaddr, args.intport, args.extaddr, args.extport); // 防止接收到的数据不是想要的数据 if(findComponentType == args.componentType) { findIdx_++; } else { ERROR_MSG("Componentbridge::process: %s not found. receive data is error!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); } } else { ERROR_MSG("Componentbridge::process: receive error!\n"); // 如果是这些辅助组件没找到则跳过 if(findComponentType == MESSAGELOG_TYPE || findComponentType == RESOURCEMGR_TYPE) { WARNING_MSG("Componentbridge::process: not found %s!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); findComponentTypes_[findIdx_] = -1; // 跳过标志 findIdx_++; } return false; } } state_ = 2; findIdx_ = 0; return false; } if(state_ == 2) { // 开始注册到所有的组件 while(findComponentTypes_[findIdx_] != UNKNOWN_COMPONENT_TYPE) { if(dispatcher().isBreakProcessing()) return false; int8 findComponentType = findComponentTypes_[findIdx_]; if(findComponentType == -1) { findIdx_++; return false; } INFO_MSG("Componentbridge::process: register self to %s...\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); if(getComponents().connectComponent(static_cast<COMPONENT_TYPE>(findComponentType), getUserUID(), 0) != 0) { ERROR_MSG("Componentbridge::register self to %s is error!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); //dispatcher().breakProcessing(); return false; } findIdx_++; return false; } } return true; }
void vfileLogger(int priority, const char *format, va_list optional_arguments) { int n = 0; int error = EXIT_SUCCESS; const int saved_errno = errno; int internalError = EXIT_SUCCESS; const int LogMask = setlogmask(0); /* Check priority against setlogmask values. */ if ((LOG_MASK (LOG_PRI (priority)) & LogMask) != 0) { //char logMsg[2048]; //char logFormat[1024]; //char *cursor = logFormat; char *buf = 0; size_t bufsize = 1024; FILE *f = open_memstream(&buf, &bufsize); if (f != NULL) { struct tm now_tm; time_t now; (void) time(&now); /*cursor += strftime(cursor,sizeof(logFormat),"%h %e %T ",localtime_r(&now, &now_tm));*/ n = strftime(f->_IO_write_ptr,f->_IO_write_end - f->_IO_write_ptr,"%h %e %T ",localtime_r(&now, &now_tm)); //f->_IO_write_ptr += strftime(f->_IO_write_ptr,f->_IO_write_end - f->_IO_write_ptr,"%h %e %T ",localtime_r(&now, &now_tm)); f->_IO_write_ptr += n; if (LogTag) { /*cursor += sprintf (cursor,"%s: ",LogTag);*/ n += fprintf(f,"%s: ",LogTag); } if (LogStat & LOG_PID) { if (LogStat & LOG_TID) { const pid_t tid = gettid(); /*cursor += sprintf (cursor, "[%d:%d]", (int) getpid (),(int) tid);*/ n += fprintf(f,"[%d:%d]", (int) getpid (),(int) tid); } else { /*cursor += sprintf (cursor, "[%d]", (int) getpid ());*/ n += fprintf(f,"[%d]", (int) getpid ()); } } if (LogStat & LOG_RDTSC) { const unsigned long long int t = rdtsc(); /*cursor += sprintf (cursor, "(%llu)",t);*/ n += fprintf(f,"(%llu)",t); } /* (LogStat & LOG_RDTSC) */ if (LogStat & LOG_CLOCK) { #if HAVE_CLOCK_GETTIME struct timespec timeStamp; if (clock_gettime(CLOCK_MONOTONIC,&timeStamp) == 0) { /*cursor += sprintf (cursor, "(%lu.%.9d)",timeStamp.tv_sec,timeStamp.tv_nsec);*/ n += fprintf(f,"(%lu.%.9d)",timeStamp.tv_sec,timeStamp.tv_nsec); } else { const int error = errno; ERROR_MSG("clock_gettime CLOCK_MONOTONIC error %d (%m)",error); } #else static unsigned int alreadyPrinted = 0; /* to avoid to print this error msg on each call */ if (unlikely(0 == alreadyPrinted)) { ERROR_MSG("clock_gettime not available on this system"); alreadyPrinted = 1; } #endif } /* (LogStat & LOG_CLOCK) */ if (LogStat & LOG_LEVEL) { switch(LOG_PRI(priority)) { case LOG_EMERG: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Emergency * %s",format);*/ n += fprintf(f, "[EMERG]"); break; case LOG_ALERT: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Alert * %s",format);*/ n += fprintf(f, "[ALERT]"); break; case LOG_CRIT: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Critical * %s",format);*/ n += fprintf(f, "[CRIT]"); break; case LOG_ERR: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Error * %s",format);*/ n += fprintf(f, "[ERROR]"); break; case LOG_WARNING: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Warning * %s",format);*/ n += fprintf(f, "[WARNING]"); break; case LOG_NOTICE: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Notice * %s",format); */ n += fprintf(f, "[NOTICE]"); break; case LOG_INFO: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Info * %s",format);*/ n += fprintf(f, "[INFO]"); break; case LOG_DEBUG: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Debug * %s",format);*/ n += fprintf(f, "[DEBUG]"); break; default: /*cursor += sprintf(cursor,"* <%d> * %s",priority,format);*/ n += fprintf(f,"[<%d>]",priority); } /* switch(priority) */ } /* (LogStat & LOG_LEVEL) */ errno = saved_errno; /* restore errno for %m format */ n += vfprintf(f, format, optional_arguments); /* Close the memory stream; this will finalize the data into a malloc'd buffer in BUF. */ fclose(f); /* * begin of the critical section. * Some of the function used below are thread cancellation points * (according to Advanced Programming in the Unix Environment 2nd ed p411) * so set the handler to avoid deadlocks and memory leaks */ cleanup_args cancelArgs; cancelArgs.buffer = buf; pthread_cleanup_push(cancel_handler, &cancelArgs); error = pthread_mutex_lock(&fileLock); if (likely(EXIT_SUCCESS == error)) { if (unlikely(LogStat & LOG_PERROR)) { /* add the format argument to the header */ const size_t n = strlen(format); const size_t size = bufsize + n + 1; char *logFormatBuffer = (char *)malloc(size); if (logFormatBuffer) { pthread_cleanup_push(free,logFormatBuffer); strcpyNcat(logFormatBuffer,buf,format); vfprintf(stderr, logFormatBuffer, optional_arguments); pthread_cleanup_pop(1); /* pop the handler and free the allocated memory */ } else { ERROR_MSG("failed to allocate %u bytes to print the msg on stderr",size); } } /* (LogStat & LOG_PERROR) */ /* file management */ if (unlikely(LOG_FILE_DURATION & LogStat)) { const time_t currentTime = time(NULL); const time_t elapsedTime = currentTime - startTime; if (unlikely(elapsedTime >= maxDuration)) { close(logFile); logFile = -1; } } /* (LOG_FILE_DURATION & LogStat) */ if (unlikely(-1 == logFile)) { error = createFile(); /* error already logged */ } if (likely(EXIT_SUCCESS == error)) { const ssize_t written = write(logFile,buf,n); if (written > 0) { if (unlikely(written != n)) { ERROR_MSG("only %d byte(s) of %d has been written to %s",written,n,fullFileName); if (LogStat & LOG_CONS) { int fd = open("/dev/console", O_WRONLY | O_NOCTTY, 0); if (fd >= 0 ) { dprintf(fd,"logMsg"); close(fd); fd = -1; } } /* (LogStat & LOG_CONS) */ if (unlikely((LogStat & LOG_FILE_SYNC_ON_ERRORS_ONLY) && (LOG_PRI(priority) <= LOG_ERR))) { /* flush data if the log priority is "upper" or equal to error */ error = fdatasync(logFile); if (error != 0) { error = errno; ERROR_MSG("fdatasync to %s error %d (%m)",fullFileName,error); } error = posix_fadvise(logFile, 0,0,POSIX_FADV_DONTNEED); /* tell the OS that log message bytes could be released from the file system cache */ if (error != 0) { ERROR_MSG("posix_fadvise to %s error %d (%m)",fullFileName,error); } } /* (unlikely((LogStat & LOG_FILE_SYNC_ON_ERRORS_ONLY) && (LOG_PRI(priority) <= LOG_ERR))) */ } /* (unlikely(written != n)) */ fileSize += written; #ifdef FILESYSTEM_PAGE_CACHE_FLUSH_THRESHOLD static size_t currentPageCacheMaxSize = 0; currentPageCacheMaxSize += written; if (currentPageCacheMaxSize >= FILESYSTEM_PAGE_CACHE_FLUSH_THRESHOLD) { /* tell the OS that log message bytes could be released from the file system cache */ if (likely(posix_fadvise(logFile, 0,0,POSIX_FADV_DONTNEED) == 0)) { currentPageCacheMaxSize = 0; DEBUG_MSG("used file system cache allowed to be flushed (size was %u)",currentPageCacheMaxSize); } else { NOTICE_MSG("posix_fadvise to %s error %d (%m), current page cache max size is %u",fullFileName,error,currentPageCacheMaxSize); } } #endif /* FILESYSTEM_PAGE_CACHE_FLUSH_THRESHOLD */ if ((LOG_FILE_ROTATE & LogStat) || (LOG_FILE_HISTO & LogStat)) { if (fileSize >= maxSize) { close(logFile); logFile = -1; } } } else if (0 == written) { WARNING_MSG("nothing has been written in %s", fullFileName); } else { error = errno; ERROR_MSG("write to %s error %d (%m)", fullFileName, error); } } /*(likely(EXIT_SUCCESS == error)) */ /* End of critical section. */ /*pthread_cleanup_pop(0); implementation can't allow to set this instruction here */ /* free allocated ressources */ internalError = pthread_mutex_unlock(&fileLock); if (internalError != EXIT_SUCCESS) { ERROR_MSG("pthread_mutex_lock fileLock error %d (%s)", internalError, strerror(internalError)); if (EXIT_SUCCESS == error) { error = internalError; } } /* (internalError != EXIT_SUCCESS) */ } else { ERROR_MSG("pthread_mutex_lock fileLock error %d (%s)", error, strerror(error)); } pthread_cleanup_pop(0); /* moved to avoid a build error, use the preprocessor to understand why * or have a look on man 3 pthread_cleanup_push: * push & pop MUST BE in the SAME lexical nesting level !!! */ free(buf); cancelArgs.buffer = buf = NULL; } else { /* open_memstream(&buf, &bufsize) == NULL */ ERROR_MSG("failed to get stream buffer"); /* TMP! display the raw message to the console */ vfprintf(stderr,format,optional_arguments); /* TODO: write the raw message to the file */ } } /* ((LOG_MASK (LOG_PRI (priority)) & LogMask) != 0) */ /* message has not to be displayed because of the current LogMask and its priority */ /*return n;*/ }
//------------------------------------------------------------------------------------- void Baseapp::onCreateBaseAnywhere(Mercury::Channel* pChannel, MemoryStream& s) { if(pChannel->isExternal()) return; std::string strInitData = ""; uint32 initDataLength = 0; PyObject* params = NULL; std::string entityType; COMPONENT_ID componentID; CALLBACK_ID callbackID; s >> entityType; s >> initDataLength; if(initDataLength > 0) { strInitData.assign((char*)(s.data() + s.rpos()), initDataLength); s.read_skip(initDataLength); } s >> componentID; s >> callbackID; if(strInitData.size() > 0) params = script::Pickler::unpickle(strInitData); Base* base = createEntityCommon(entityType.c_str(), params); Py_XDECREF(params); if(base == NULL) return; // 如果不是在发起创建entity的baseapp上创建则需要转发回调到发起方 if(componentID != componentID_) { Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(componentID); if(cinfos == NULL || cinfos->pChannel == NULL) { ForwardItem* pFI = new ForwardItem(); pFI->pHandler = NULL; pFI->bundle.newMessage(BaseappInterface::onCreateBaseAnywhereCallback); pFI->bundle << callbackID; pFI->bundle << entityType; pFI->bundle << base->getID(); pFI->bundle << componentID_; forward_messagebuffer_.push(componentID, pFI); WARNING_MSG("Baseapp::onCreateBaseAnywhere: not found baseapp, message is buffered.\n"); return; } Mercury::Channel* lpChannel = cinfos->pChannel; // 需要baseappmgr转发给目的baseapp Mercury::Bundle forwardbundle; forwardbundle.newMessage(BaseappInterface::onCreateBaseAnywhereCallback); forwardbundle << callbackID; forwardbundle << entityType; forwardbundle << base->getID(); forwardbundle << componentID_; forwardbundle.send(this->getNetworkInterface(), lpChannel); } else { ENTITY_ID eid = base->getID(); _onCreateBaseAnywhereCallback(NULL, callbackID, entityType, eid, componentID_); } }
int kbeMainT(int argc, char * argv[], COMPONENT_TYPE componentType, int32 extlisteningPort_min = -1, int32 extlisteningPort_max = -1, const char * extlisteningInterface = "", int32 intlisteningPort = 0, const char * intlisteningInterface = "") { setEvns(); startLeakDetection(componentType, g_componentID); g_componentType = componentType; DebugHelper::initHelper(componentType); INFO_MSG( "-----------------------------------------------------------------------------------------\n\n\n"); #ifdef USE_OPENSSL KBEKey kbekey(Resmgr::getSingleton().matchPath("key/") + "kbengine_public.key", Resmgr::getSingleton().matchPath("key/") + "kbengine_private.key"); #endif Resmgr::getSingleton().print(); Mercury::EventDispatcher dispatcher; DebugHelper::getSingleton().pDispatcher(&dispatcher); const ChannelCommon& channelCommon = g_kbeSrvConfig.channelCommon(); Mercury::g_SOMAXCONN = g_kbeSrvConfig.tcp_SOMAXCONN(g_componentType); Mercury::NetworkInterface networkInterface(&dispatcher, extlisteningPort_min, extlisteningPort_max, extlisteningInterface, channelCommon.extReadBufferSize, channelCommon.extWriteBufferSize, (intlisteningPort != -1) ? htons(intlisteningPort) : -1, intlisteningInterface, channelCommon.intReadBufferSize, channelCommon.intWriteBufferSize); DebugHelper::getSingleton().pNetworkInterface(&networkInterface); g_kbeSrvConfig.updateInfos(true, componentType, g_componentID, networkInterface.intaddr(), networkInterface.extaddr()); if(getUserUID() <= 0) { WARNING_MSG(boost::format("invalid UID(%1%) <= 0, please check UID for environment!\n") % getUserUID()); } Componentbridge* pComponentbridge = new Componentbridge(networkInterface, componentType, g_componentID); SERVER_APP app(dispatcher, networkInterface, componentType, g_componentID); START_MSG(COMPONENT_NAME_EX(componentType), g_componentID); if(!app.initialize()) { ERROR_MSG("app::initialize() is error!\n"); SAFE_RELEASE(pComponentbridge); app.finalise(); return -1; } INFO_MSG(boost::format("---- %1% is running ----\n") % COMPONENT_NAME_EX(componentType)); #if KBE_PLATFORM == PLATFORM_WIN32 printf("[INFO]: %s", (boost::format("---- %1% is running ----\n") % COMPONENT_NAME_EX(componentType)).str().c_str()); wchar_t exe_path[MAX_PATH]; memset(exe_path, 0, MAX_PATH * sizeof(wchar_t)); GetCurrentDirectory(MAX_PATH, exe_path); char* ccattr = strutil::wchar2char(exe_path); printf("Writing to: %s/logs/%s.*.log\n\n", ccattr, COMPONENT_NAME_EX(componentType)); free(ccattr); #endif int ret = app.run(); SAFE_RELEASE(pComponentbridge); app.finalise(); INFO_MSG(boost::format("%1%(%2%) has shut down.\n") % COMPONENT_NAME_EX(componentType) % g_componentID); return ret; }
void vconsoleLogger(int priority, const char *format, va_list optional_arguments) { /*int n = 0;*/ const int saved_errno = errno; const int LogMask = setlogmask(0); /* no cancellation point is currently used in this function * (according to Advanced Programming in the Unix Environment 2nd ed p411) * so there is no thread cancellation clean-up handlers defined */ /* Check for invalid bits. */ if (unlikely(priority & ~(LOG_PRIMASK | LOG_FACMASK))) { /*syslog(INTERNALLOG, "syslog: unknown facility/priority: %x", pri);*/ WARNING_MSG("unknown facility/priority: %x", priority); priority &= LOG_PRIMASK | LOG_FACMASK; } /* Check priority against setlogmask values. */ if ((LOG_MASK (LOG_PRI (priority)) & LogMask) != 0) { char *buf = 0; size_t bufsize = 1024; /*char logFormat[1024]; char *cursor = logFormat;*/ FILE *f = open_memstream(&buf, &bufsize); if (f != NULL) { struct tm now_tm; time_t now; (void) time(&now); /*cursor += strftime(cursor,sizeof(logFormat),"%h %e %T ",localtime_r(&now, &now_tm));*/ f->_IO_write_ptr += strftime(f->_IO_write_ptr,f->_IO_write_end - f->_IO_write_ptr,"%h %e %T ",localtime_r(&now, &now_tm)); if (LogTag) { //cursor += sprintf (cursor,"%s: ",LogTag); fprintf(f,"%s: ",LogTag); } if (LogStat & LOG_PID) { if (LogStat & LOG_TID) { const pid_t tid = gettid(); /*cursor += sprintf (cursor, "[%d:%d]", (int) getpid (),(int) tid);*/ fprintf(f,"[%d:%d]", (int) getpid (),(int) tid); } else { /*cursor += sprintf (cursor, "[%d]", (int) getpid ());*/ fprintf(f,"[%d]", (int) getpid ()); } } if (LogStat & LOG_RDTSC) { const unsigned long long int t = rdtsc(); /*cursor += sprintf (cursor, "(%llu)",t);*/ fprintf(f,"(%llu)",t); } /* (LogStat & LOG_RDTSC) */ if (LogStat & LOG_CLOCK) { #if HAVE_CLOCK_GETTIME struct timespec timeStamp; if (clock_gettime(CLOCK_MONOTONIC,&timeStamp) == 0) { /*cursor += sprintf (cursor, "(%lu.%.9d)",timeStamp.tv_sec,timeStamp.tv_nsec);*/ fprintf(f,"(%lu.%.9d)",timeStamp.tv_sec,timeStamp.tv_nsec); } else { const int error = errno; ERROR_MSG("clock_gettime CLOCK_MONOTONIC error %d (%m)",error); } #else static unsigned int alreadyPrinted = 0; /* to avoid to print this error msg on each call */ if (unlikely(0 == alreadyPrinted)) { ERROR_MSG("clock_gettime not available on this system"); alreadyPrinted = 1; } #endif } /* (LogStat & LOG_CLOCK) */ if (LogStat & LOG_LEVEL) { switch(LOG_PRI(priority)) { case LOG_EMERG: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Emergency * %s",format);*/ fprintf(f,"[EMERG] %s",format); break; case LOG_ALERT: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Alert * %s",format);*/ fprintf(f,"[ALERT] %s",format); break; case LOG_CRIT: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Critical * %s",format);*/ fprintf(f,"[CRIT] %s",format); break; case LOG_ERR: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Error * %s",format);*/ fprintf(f,"[ERROR] %s",format); break; case LOG_WARNING: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Warning * %s",format);*/ fprintf(f,"[WARNING] %s",format); break; case LOG_NOTICE: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Notice * %s",format); */ fprintf(f,"[NOTICE] %s",format); break; case LOG_INFO: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Info * %s",format);*/ fprintf(f,"[INFO] %s",format); break; case LOG_DEBUG: /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"* Debug * %s",format);*/ fprintf(f,"[DEBUG] %s",format); break; default: /*cursor += sprintf(cursor,"* <%d> * %s",priority,format);*/ fprintf(f,"[<%d>] %s",priority,format); } /* switch(priority) */ } else { /* (LogStat & LOG_LEVEL) */ /*cursor += snprintf(cursor,sizeof(logFormat) - (cursor - logFormat),"%s",format);*/ fprintf(f,"%s",format); } /*n =*/ /*vfprintf(stderr,logFormat,optional_arguments);*/ /* Close the memory stream; this will finalize the data into a malloc'd buffer in BUF. */ fclose(f); errno = saved_errno; /* restore errno for %m format */ vfprintf(stderr,buf,optional_arguments); free(buf); } else { /* We cannot get a stream: try to write directly to the console (warning may be splitted by other msg) */ struct tm now_tm; time_t now; char buffer[20]; WARNING_MSG("failed to get stream buffer, using the console without buffering instead"); (void) time(&now); strftime(buffer,sizeof(buffer),"%h %e %T ",localtime_r(&now, &now_tm)); fprintf(stderr,"%s",buffer); if (LogTag) { printf("%s: ",LogTag); } if (LogStat & LOG_PID) { if (LogStat & LOG_TID) { const pid_t tid = gettid(); fprintf(stderr,"[%d:%d]", (int) getpid (),(int) tid); } else { fprintf(stderr,"[%d]", (int) getpid ()); } } if (LogStat & LOG_RDTSC) { const unsigned long long int t = rdtsc(); fprintf(stderr,"(%llu)",t); } /* (LogStat & LOG_RDTSC) */ if (LogStat & LOG_CLOCK) { #if HAVE_CLOCK_GETTIME struct timespec timeStamp; if (clock_gettime(CLOCK_MONOTONIC,&timeStamp) == 0) { fprintf(stderr,"(%lu.%.9d)",timeStamp.tv_sec,timeStamp.tv_nsec); } else { const int error = errno; ERROR_MSG("clock_gettime CLOCK_MONOTONIC error %d (%m)",error); } #else static unsigned int alreadyPrinted = 0; /* to avoid to print this error msg on each call */ if (unlikely(0 == alreadyPrinted)) { ERROR_MSG("clock_gettime not available on this system"); alreadyPrinted = 1; } #endif } /* (LogStat & LOG_CLOCK) */ if (LogStat & LOG_LEVEL) { switch(LOG_PRI(priority)) { case LOG_EMERG: fprintf(stderr,"* Emergency * "); break; case LOG_ALERT: fprintf(stderr,"* Alert * "); break; case LOG_CRIT: fprintf(stderr,"* Critical * "); break; case LOG_ERR: fprintf(stderr,"* Error * "); break; case LOG_WARNING: fprintf(stderr,"* Warning * "); break; case LOG_NOTICE: fprintf(stderr,"* Notice * "); break; case LOG_INFO: fprintf(stderr,"* Info * "); break; case LOG_DEBUG: fprintf(stderr,"* Debug * "); break; default: fprintf(f,"* <%d> * ",priority); } /* switch(priority) */ } vfprintf(stderr,format,optional_arguments); } } /* ((LOG_MASK (LOG_PRI (priority)) & LogMask) != 0) */ /* message has not to be displayed because of the current LogMask and its priority */ /*return n;*/ }
//------------------------------------------------------------------------------------- bool RestoreEntityHandler::process() { Components::COMPONENTS& cts = Components::getSingleton().getComponents(CELLAPP_TYPE); Mercury::Channel* pChannel = NULL; if(cts.size() > 0) { Components::COMPONENTS::iterator ctiter = cts.begin(); if((*ctiter).pChannel == NULL) return true; pChannel = (*ctiter).pChannel; } if(pChannel == NULL) return true; int count = 0; // 首先需要找到这个cell上的space // KBE_ASSERT(restoreSpaces_.size() > 0); // 如果spaceEntity不在这个baseapp上创建则继续等待 // 当spaceEntity的cell创建好了之后会广播给所有的baseapp, 每个baseapp // 去判断是否有需要恢复的entity if(restoreSpaces_.size() > 0) { if(timestamp() - tickReport_ > uint64( 3 * stampsPerSecond() )) { tickReport_ = timestamp(); INFO_MSG(boost::format("RestoreEntityHandler::process(%3%): wait for localSpace to get cell!, entitiesSize(%1%), spaceSize=%2%\n") % entities_.size() % restoreSpaces_.size() % cellappID_); } int spaceCellCount = 0; // 必须等待space恢复 std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin(); for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++) { Base* pBase = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id); if(pBase) { if(++count > (int)g_kbeSrvConfig.getBaseApp().entityRestoreSize) { return true; } if((*restoreSpacesIter).creatingCell == false) { (*restoreSpacesIter).creatingCell = true; pBase->restoreCell(NULL); } else { if(pBase->cellMailbox() == NULL) { return true; } else { spaceCellCount++; if(!(*restoreSpacesIter).processed) { (*restoreSpacesIter).processed = true; pBase->onRestore(); } } } } else { ERROR_MSG(boost::format("RestoreEntityHandler::process(%1%): lose space(%2%).\n") % cellappID_ % (*restoreSpacesIter).id); } } if(spaceCellCount != (int)restoreSpaces_.size()) return true; // 通知其他baseapp, space恢复了cell if(!broadcastOtherBaseapps_) { broadcastOtherBaseapps_ = true; INFO_MSG(boost::format("RestoreEntityHandler::process(%1%): begin broadcast-spaceGetCell to otherBaseapps...\n") % cellappID_); std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin(); for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++) { Base* pBase = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id); bool destroyed = (pBase == NULL || pBase->isDestroyed()); COMPONENT_ID baseappID = g_componentID; COMPONENT_ID cellappID = 0; SPACE_ID spaceID = (*restoreSpacesIter).spaceID; ENTITY_ID spaceEntityID = (*restoreSpacesIter).id; ENTITY_SCRIPT_UID utype = 0; if(!destroyed) { utype = pBase->scriptModule()->getUType(); cellappID = pBase->cellMailbox()->componentID(); } spaceIDs_.erase(std::remove(spaceIDs_.begin(), spaceIDs_.end(), spaceID), spaceIDs_.end()); Mercury::Channel* pChannel = NULL; Components::COMPONENTS& cts = Componentbridge::getComponents().getComponents(BASEAPP_TYPE); Components::COMPONENTS::iterator comsiter = cts.begin(); for(; comsiter != cts.end(); comsiter++) { pChannel = (*comsiter).pChannel; if(pChannel) { INFO_MSG(boost::format("RestoreEntityHandler::process(%5%): broadcast baseapp[%1%, %2%], spaceID[%3%], utype[%4%]...\n") % (*comsiter).cid % pChannel->c_str() % spaceID % utype % cellappID_); Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::onRestoreSpaceCellFromOtherBaseapp); (*pBundle) << baseappID << cellappID << spaceID << spaceEntityID << utype << destroyed; pBundle->send(Baseapp::getSingleton().getNetworkInterface(), pChannel); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } } } } } if(spaceIDs_.size() > 0) { if(timestamp() - tickReport_ > uint64( 3 * stampsPerSecond() )) { tickReport_ = timestamp(); INFO_MSG(boost::format("RestoreEntityHandler::process(%1%): wait for otherBaseappSpaces to get cell!, entitiesSize(%2%), spaceSize=%3%\n") % cellappID_ % entities_.size() % spaceIDs_.size()); } return true; } // 恢复其他entity std::vector<RestoreData>::iterator iter = entities_.begin(); for(; iter != entities_.end(); ) { RestoreData& data = (*iter); Base* pBase = Baseapp::getSingleton().findEntity(data.id); if(pBase) { if(++count > g_kbeSrvConfig.getBaseApp().entityRestoreSize) { return true; } if(pBase->cellMailbox() != NULL) { if(!data.processed) { data.processed = true; pBase->onRestore(); } iter = entities_.erase(iter); } else { if(!data.creatingCell) { data.creatingCell = true; EntityMailboxAbstract* cellMailbox = NULL; std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin(); for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++) { Base* pSpace = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id); if(pSpace && pBase->spaceID() == pSpace->spaceID()) { cellMailbox = pSpace->cellMailbox(); break; } } if(cellMailbox == NULL) { restoreSpacesIter = otherRestoredSpaces_.begin(); for(; restoreSpacesIter != otherRestoredSpaces_.end(); restoreSpacesIter++) { if(pBase->spaceID() == (*restoreSpacesIter).spaceID && (*restoreSpacesIter).cell) { cellMailbox = (*restoreSpacesIter).cell; break; } } } if(cellMailbox) { pBase->restoreCell(cellMailbox); } else { ENTITY_ID delID = pBase->id(); pBase->destroy(); WARNING_MSG(boost::format("RestoreEntityHandler::process(%1%): not fount spaceCell, killed base(%2%)!") % cellappID_ % delID); if(Baseapp::getSingleton().findEntity(delID) == NULL) iter = entities_.erase(iter); continue; } } iter++; } } else { iter = entities_.erase(iter); } } if(entities_.size() == 0) { std::vector<RestoreData>::iterator restoreSpacesIter = otherRestoredSpaces_.begin(); for(; restoreSpacesIter != otherRestoredSpaces_.end(); restoreSpacesIter++) { if((*restoreSpacesIter).cell) { Py_DECREF((*restoreSpacesIter).cell); (*restoreSpacesIter).cell = NULL; } } otherRestoredSpaces_.clear(); inProcess_ = false; Baseapp::getSingleton().onRestoreEntitiesOver(this); return false; } return true; }
//------------------------------------------------------------------------------------- void Cellappmgr::reqCreateInNewSpace(Network::Channel* pChannel, MemoryStream& s) { std::string entityType; ENTITY_ID id; COMPONENT_ID componentID; bool hasClient; // 如果cellappIndex为0,则代表不强制指定cellapp // 非0的情况下,选择的cellapp可以用1,2,3,4来代替 // 假如预期有4个cellapp, 假如不够4个, 只有3个, 那么4代表1 uint32 cellappIndex = 0; s >> entityType; s >> id; s >> cellappIndex; s >> componentID; s >> hasClient; static SPACE_ID spaceID = 1; Network::Bundle* pBundle = Network::Bundle::createPoolObject(); (*pBundle).newMessage(CellappInterface::onCreateInNewSpaceFromBaseapp); (*pBundle) << entityType; (*pBundle) << id; (*pBundle) << spaceID++; (*pBundle) << componentID; (*pBundle) << hasClient; (*pBundle).append(&s); s.done(); uint32 cellappSize = cellapp_cids_.size(); if (cellappSize > 0) { updateBestCellapp(); // 选择特定的cellapp创建space if (cellappIndex > 0) { uint32 index = (cellappIndex - 1) % cellappSize; bestCellappID_ = cellapp_cids_[index]; } else if (bestCellappID_ == 0 && numLoadBalancingApp() == 0) { ERROR_MSG(fmt::format("Cellappmgr::reqCreateInNewSpace: Unable to allocate cellapp for load balancing! entityType={}, entityID={}, componentID={}, cellappSize={}.\n", entityType, id, componentID, cellappSize)); } } Components::ComponentInfos* cinfos = NULL; if (bestCellappID_ > 0) cinfos = Components::getSingleton().findComponent(CELLAPP_TYPE, bestCellappID_); if (cinfos == NULL || cinfos->pChannel == NULL || cinfos->state != COMPONENT_STATE_RUN) { WARNING_MSG("Cellappmgr::reqCreateInNewSpace: not found cellapp, message is buffered.\n"); ForwardItem* pFI = new AppForwardItem(); pFI->pHandler = NULL; pFI->pBundle = pBundle; if (cellappIndex == 0 || bestCellappID_ == 0) forward_anywhere_cellapp_messagebuffer_.push(pFI); else forward_cellapp_messagebuffer_.push(bestCellappID_, pFI); return; } else { cinfos->pChannel->send(pBundle); } std::map< COMPONENT_ID, Cellapp >::iterator cellapp_iter = cellapps_.find(bestCellappID_); DEBUG_MSG(fmt::format("Cellappmgr::reqCreateInNewSpace: entityType={}, entityID={}, componentID={}, cellapp(cid={}, load={}, numEntities={}).\n", entityType, id, componentID, bestCellappID_, cellapp_iter->second.load(), cellapp_iter->second.numEntities())); // 预先将实体数量增加 if (cellapp_iter != cellapps_.end()) { cellapp_iter->second.incNumEntities(); } }
//------------------------------------------------------------------------------------- void Components::addComponent(int32 uid, const char* username, COMPONENT_TYPE componentType, COMPONENT_ID componentID, COMPONENT_ORDER globalorderid, COMPONENT_ORDER grouporderid, uint32 intaddr, uint16 intport, uint32 extaddr, uint16 extport, std::string& extaddrEx, uint32 pid, float cpu, float mem, uint32 usedmem, uint64 extradata, uint64 extradata1, uint64 extradata2, uint64 extradata3, Network::Channel* pChannel) { COMPONENTS& components = getComponents(componentType); if(!checkComponents(uid, componentID, pid)) return; ComponentInfos* cinfos = findComponent(componentType, uid, componentID); if(cinfos != NULL) { WARNING_MSG(fmt::format("Components::addComponent[{}]: uid:{}, username:{}, " "componentType:{}, componentID:{} is exist!\n", COMPONENT_NAME_EX(componentType), uid, username, (int32)componentType, componentID)); return; } ComponentInfos componentInfos; componentInfos.pIntAddr.reset(new Network::Address(intaddr, intport)); componentInfos.pExtAddr.reset(new Network::Address(extaddr, extport)); if(extaddrEx.size() > 0) strncpy(componentInfos.externalAddressEx, extaddrEx.c_str(), MAX_NAME); componentInfos.uid = uid; componentInfos.cid = componentID; componentInfos.pChannel = pChannel; componentInfos.componentType = componentType; componentInfos.groupOrderid = 1; componentInfos.globalOrderid = 1; componentInfos.mem = mem; componentInfos.cpu = cpu; componentInfos.usedmem = usedmem; componentInfos.extradata = extradata; componentInfos.extradata1 = extradata1; componentInfos.extradata2 = extradata2; componentInfos.extradata3 = extradata3; componentInfos.pid = pid; if(pChannel) pChannel->componentID(componentID); strncpy(componentInfos.username, username, MAX_NAME); _globalOrderLog[uid]++; switch(componentType) { case BASEAPP_TYPE: _baseappGrouplOrderLog[uid]++; componentInfos.groupOrderid = _baseappGrouplOrderLog[uid]; break; case CELLAPP_TYPE: _cellappGrouplOrderLog[uid]++; componentInfos.groupOrderid = _cellappGrouplOrderLog[uid]; break; case LOGINAPP_TYPE: _loginappGrouplOrderLog[uid]++; componentInfos.groupOrderid = _loginappGrouplOrderLog[uid]; break; default: break; }; if(grouporderid > 0) componentInfos.groupOrderid = grouporderid; if(globalorderid > 0) componentInfos.globalOrderid = globalorderid; else componentInfos.globalOrderid = _globalOrderLog[uid]; if(cinfos == NULL) components.push_back(componentInfos); else *cinfos = componentInfos; INFO_MSG(fmt::format("Components::addComponent[{}], uid={}, " "componentID={}, globalorderid={}, grouporderid={}, totalcount={}\n", COMPONENT_NAME_EX(componentType), uid, componentID, ((int32)componentInfos.globalOrderid), ((int32)componentInfos.groupOrderid), components.size())); if(_pHandler) _pHandler->onAddComponent(&componentInfos); }
//------------------------------------------------------------------------------------- bool Components::updateComponentInfos(const Components::ComponentInfos* info) { // 不对其他machine做处理 if(info->componentType == MACHINE_TYPE) { return true; } Network::EndPoint epListen; epListen.socket(SOCK_STREAM); if (!epListen.good()) { ERROR_MSG("Components::updateComponentInfos: couldn't create a socket\n"); return true; } epListen.setnonblocking(true); while(true) { fd_set frds, fwds; struct timeval tv = { 0, 300000 }; // 100ms FD_ZERO( &frds ); FD_ZERO( &fwds ); FD_SET((int)epListen, &frds); FD_SET((int)epListen, &fwds); if(epListen.connect(info->pIntAddr->port, info->pIntAddr->ip) == -1) { int selgot = select(epListen+1, &frds, &fwds, NULL, &tv); if(selgot > 0) { break; } WARNING_MSG(fmt::format("Components::updateComponentInfos: couldn't connect to:{}\n", info->pIntAddr->c_str())); return false; } } epListen.setnodelay(true); Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); // 由于COMMON_NETWORK_MESSAGE不包含client, 如果是bots, 我们需要单独处理 if(info->componentType != BOTS_TYPE) { COMMON_NETWORK_MESSAGE(info->componentType, (*pBundle), lookApp); } else { (*pBundle).newMessage(BotsInterface::lookApp); } epListen.send(pBundle->pCurrPacket()->data(), pBundle->pCurrPacket()->wpos()); Network::Bundle::ObjPool().reclaimObject(pBundle); fd_set fds; struct timeval tv = { 0, 300000 }; // 100ms FD_ZERO( &fds ); FD_SET((int)epListen, &fds); int selgot = select(epListen+1, &fds, NULL, NULL, &tv); if(selgot == 0) { // 超时, 可能对方繁忙 return true; } else if(selgot == -1) { return true; } else { COMPONENT_TYPE ctype; COMPONENT_ID cid; int8 istate = 0; ArraySize entitySize = 0, cellSize = 0; int32 clientsSize = 0, proxicesSize = 0; uint32 telnet_port = 0; Network::TCPPacket packet; packet.resize(255); int recvsize = sizeof(ctype) + sizeof(cid) + sizeof(istate); if(info->componentType == CELLAPP_TYPE) { recvsize += sizeof(entitySize) + sizeof(cellSize) + sizeof(telnet_port); } if(info->componentType == BASEAPP_TYPE) { recvsize += sizeof(entitySize) + sizeof(clientsSize) + sizeof(proxicesSize) + sizeof(telnet_port); } int len = epListen.recv(packet.data(), recvsize); packet.wpos(len); if(recvsize != len) { WARNING_MSG(fmt::format("Components::updateComponentInfos: packet invalid(recvsize({}) != ctype_cid_len({}).\n" , len, recvsize)); if(len == 0) return false; return true; } packet >> ctype >> cid >> istate; if(ctype == CELLAPP_TYPE) { packet >> entitySize >> cellSize >> telnet_port; } if(ctype == BASEAPP_TYPE) { packet >> entitySize >> clientsSize >> proxicesSize >> telnet_port; }