设为首页 收藏本站
查看: 1813|回复: 0

[经验分享] MongoDB源码分析——mongod程序源码入口分析

[复制链接]

尚未签到

发表于 2015-7-6 08:52:11 | 显示全部楼层 |阅读模式
  
  


Edit



说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他部分,如果有什么错误请大家指出,谢谢。



源码版本为MongoDB 2.6分支




mongod程序源码入口分析
  为了理解MongoDB的运行机制,首先要对主要运行流程有个大概理解,我们首先从main函数开始。mongod项目的main函数位于db.cpp文件中,出于跨平台的需求,对Windows和Linux平台提供了两个main函数:

#if defined(_WIN32)
int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) {
WindowsCommandLine wcl(argc, argvW, envpW);
int exitCode = mongoDbMain(argc, wcl.argv(), wcl.envp());
::_exit(exitCode);
}
#else
int main(int argc, char* argv[], char** envp) {
int exitCode = mongoDbMain(argc, argv, envp);
::_exit(exitCode);
}
#endif

  上面代码中wmain代码对命令行做了编码转换,然后统一调用了mongoDbMain函数,进入流程处理,下面具体分析mongoDbMain函数:

static int mongoDbMain(int argc, char* argv[], char **envp) {
//静态观察,大概作用是main函数结束时候局部static staticObserver会首先释放
//其他地方通过观察StaticObserver 的成员变量_destroyingStatics来判断mongoDbMain结束。
static StaticObserver staticObserver;
#if defined(_WIN32)
mongo::reportEventToSystem = &mongo::reportEventToSystemImpl;
#endif
getcurns = ourgetns;
setupSignalHandlers();
dbExecCommand = argv[0];
srand(curTimeMicros());
{
//判断是否为系统是否为小端模式,MongoDB暂时不支持大端模式服务器。
unsigned x = 0x12345678;
unsigned char& b = (unsigned char&) x;
if ( b != 0x78 ) {
out() startWorkers();
// Starts a background thread that rebuilds all incomplete indices.
indexRebuilder.go();
//开始监听
listen(listenPort);
// listen() will return when exit code closes its socket.
exitCleanly(EXIT_NET_ERROR);
}

  从上面的_initAndListen函数中可以看到,并没有开始监听客户端请求,只是做了一些数据库准备工作,最后才调用listen(listenPort)函数对端口进行监听,下面继续分析listen函数:

void listen(int port) {
//testTheDb();
MessageServer::Options options;
options.port = port;
options.ipList = serverGlobalParams.bind_ip;
MessageServer * server = createServer( options , new MyMessageHandler() );
server->setAsTimeTracker();
// we must setupSockets prior to logStartup() to avoid getting too high
// a file descriptor for our calls to select()
//初始化Socket,然后调用listen函数开始监听
server->setupSockets();
logStartup();
//后台启动数据分片线程
startReplication();
//如果设置了--httpinterface参数,则会启动web线程线程监听http请求
if (serverGlobalParams.isHttpInterfaceEnabled)
boost::thread web( boost::bind(&webServerThread, new RestAdminAccess() /* takes ownership */));
server->run();
}

  MessageServer 是消息服务的基类,createServer返回的是他的子类PortMessageServer的对象,PortMessageServer中重写了虚函数run,客户端连接处理又被延迟到了PortMessageServer::run()函数中。

class MessageServer {
public:
struct Options {
int port;                   // port to bind to
string ipList;             // addresses to bind to
Options() : port(0), ipList("") {}
};
virtual ~MessageServer() {}
virtual void run() = 0;
virtual void setAsTimeTracker() = 0;
virtual void setupSockets() = 0;
};
class Listener : boost::noncopyable {
public:
void initAndListen(); // never returns unless error (start a thread)
/* spawn a thread, etc., then return */
virtual void accepted(boost::shared_ptr psocket, long long connectionId );
virtual void acceptedMP(MessagingPort *mp);
...
}
class PortMessageServer : public MessageServer , public Listener {
...
}

  下面继续分析PortMessageServer::run()函数:

void run() {
initAndListen();
}

  由于initAndListen函数在mongodb中Windows和Linux两部分分开来实现,我们只分析Linux部分,两部分原来相同,都是使用select来监听客户端请求。下面代码我删除部分,只保留处理逻辑。

#if !defined(_WIN32)
void Listener::initAndListen() {
if (!_setupSocketsSuccessful) {
return;
}
SOCKET maxfd = 0; // needed for select()
for (unsigned i = 0; i < _socks.size(); i++) {
if (_socks > maxfd)
maxfd = _socks;
}
...
struct timeval maxSelectTime;
while ( ! inShutdown() ) {
fd_set fds[1];
FD_ZERO(fds);
for (vector::iterator it=_socks.begin(), end=_socks.end(); it != end; ++it) {
FD_SET(*it, fds);
}
maxSelectTime.tv_sec = 0;
maxSelectTime.tv_usec = 10000;
const int ret = select(maxfd+1, fds, NULL, NULL, &maxSelectTime);
...
for (vector::iterator it=_socks.begin(), end=_socks.end(); it != end; ++it) {
if (! (FD_ISSET(*it, fds)))
continue;
SockAddr from;
int s = accept(*it, from.raw(), &from.addressSize);
...
long long myConnectionNumber = globalConnectionNumber.addAndFetch(1);
...
boost::shared_ptr pnewSock( new Socket(s, from) );
#ifdef MONGO_SSL
if (_ssl) {
pnewSock->secureAccepted(_ssl);
}
#endif
accepted( pnewSock , myConnectionNumber );
}
}
}
#else

  上面是一个标准的服务端socket select模型,每当有客户端socket连接时,accept成功后调用accepted函数处理。

void Listener::accepted(boost::shared_ptr psocket, long long connectionId ) {
MessagingPort* port = new MessagingPort(psocket);
port->setConnectionId( connectionId );
acceptedMP( port );
}

  此处调用的PortMessageServer对象的acceptedMP成员函数(PortMessageServer是Listener的子类),这里我们看到了一个新的类MessagingPort,MessagingPort封装了Message的发送、接收等操作,若有需求以后再具体分析。

virtual void acceptedMP(MessagingPort * p) {
...
pthread_attr_t attrs;
pthread_attr_init(&attrs);
pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
static const size_t STACK_SIZE = 1024*1024; // if we change this we need to update the warning
struct rlimit limits;
pthread_t thread;
HandleIncomingMsgParam* himParam = new HandleIncomingMsgParam(p, _handler);
int failed = pthread_create(&thread, &attrs, &handleIncomingMsg, himParam);
pthread_attr_destroy(&attrs);
}

  acceptedMP接收到消息后建立一个后台线程,在后台线程中执行handleIncomingMsg函数,处理客户端连接。

  static void* handleIncomingMsg(void* arg) {
TicketHolderReleaser connTicketReleaser( &Listener::globalTicketHolder );
scoped_ptr himArg(static_cast(arg));
MessagingPort* inPort = himArg->inPort;
MessageHandler* handler = himArg->handler;
...
inPort->psock->setLogLevel(logger::LogSeverity::Debug(1));
scoped_ptr p( inPort );
string otherSide;
Message m;
try {
LastError * le = new LastError();
lastError.reset( le ); // lastError now has ownership
handler->connected( p.get() );
while ( ! inShutdown() ) {
m.reset();
p->psock->clearCounters();
if ( ! p->recv(m) ) {
...
}
handler->process( m , p.get() , le );
networkCounter.hit( p->psock->getBytesIn() , p->psock->getBytesOut() );
}
}
...
handler->disconnected( p.get() );
return NULL;
}
};

  以上代码可以看出,服务端在接收到客户端连接请求后建立连接,然后创建后台线程,在线程中使用while循环不断的接收Message,然后调用handler的process处理。handler->connected里面只是再次调用Client::initThread(“conn”, p),这个问题之前已经分析过。
最后一个问题,handler对象其实就是createServer时候传入的第二个参数new MyMessageHandler();

class MessageHandler {
public:
virtual ~MessageHandler() {}
/**
* called once when a socket is connected
*/
virtual void connected( AbstractMessagingPort* p ) = 0;
/**
* called every time a message comes in
* handler is responsible for responding to client
*/
virtual void process( Message& m , AbstractMessagingPort* p , LastError * err ) = 0;
/**
* called once when a socket is disconnected
*/
virtual void disconnected( AbstractMessagingPort* p ) = 0;
};
class MyMessageHandler : public MessageHandler {
...
}

  至此mongod的整个消息处理轮廓已经出来了,其他的部分将会在后续的部分中继续分析



%23%23%20mongod%u7A0B%u5E8F%u5165%u53E3%u5206%u6790%0A%20%20%0A%20%20%u4E3A%u4E86%u7406%u89E3MongoDB%u7684%u8FD0%u884C%u673A%u5236%uFF0C%u9996%u5148%u8981%u5BF9%u4E3B%u8981%u8FD0%u884C%u6D41%u7A0B%u6709%u4E2A%u5927%u6982%u7406%u89E3%uFF0C%u6211%u4EEC%u9996%u5148%u4ECEmain%u51FD%u6570%u5F00%u59CB%u3002mongod%u9879%u76EE%u7684main%u51FD%u6570%u4F4D%u4E8Edb.cpp%u6587%u4EF6%u4E2D%uFF0C%u51FA%u4E8E%u8DE8%u5E73%u53F0%u7684%u9700%u6C42%uFF0C%u5BF9Windows%u548CLinux%u5E73%u53F0%u63D0%u4F9B%u4E86%u4E24%u4E2Amain%u51FD%u6570%uFF1A%0A%09%0A%0A%20%20%20%20%23if%20defined%28_WIN32%29%0A%09int%20wmain%28int%20argc%2C%20wchar_t*%20argvW%5B%5D%2C%20wchar_t*%20envpW%5B%5D%29%20%7B%0A%09%20%20%20%20WindowsCommandLine%20wcl%28argc%2C%20argvW%2C%20envpW%29%3B%0A%09%20%20%20%20int%20exitCode%20%3D%20mongoDbMain%28argc%2C%20wcl.argv%28%29%2C%20wcl.envp%28%29%29%3B%0A%09%20%20%20%20%3A%3A_exit%28exitCode%29%3B%0A%09%7D%0A%09%23else%0A%09int%20main%28int%20argc%2C%20char*%20argv%5B%5D%2C%20char**%20envp%29%20%7B%0A%09%20%20%20%20int%20exitCode%20%3D%20mongoDbMain%28argc%2C%20argv%2C%20envp%29%3B%0A%09%20%20%20%20%3A%3A_exit%28exitCode%29%3B%0A%09%7D%0A%09%23endif%0A%0A%u4E0A%u9762%u4EE3%u7801%u4E2Dwmain%u4EE3%u7801%u5BF9%u547D%u4EE4%u884C%u505A%u4E86%u7F16%u7801%u8F6C%u6362%uFF0C%u7136%u540E%u7EDF%u4E00%u8C03%u7528%u4E86mongoDbMain%u51FD%u6570%uFF0C%u8FDB%u5165%u6D41%u7A0B%u5904%u7406%uFF0C%u4E0B%u9762%u5177%u4F53%u5206%u6790mongoDbMain%u51FD%u6570%3A%0A%0A%20%20%20%20static%20int%20mongoDbMain%28int%20argc%2C%20char*%20argv%5B%5D%2C%20char%20**envp%29%20%7B%0A%09%20%20%20%20//%u9759%u6001%u89C2%u5BDF%uFF0C%u5927%u6982%u4F5C%u7528%u662Fmain%u51FD%u6570%u7ED3%u675F%u65F6%u5019%u5C40%u90E8static%20staticObserver%u4F1A%u9996%u5148%u91CA%u653E%0A%09%20%20%20%20//%u5176%u4ED6%u5730%u65B9%u901A%u8FC7%u89C2%u5BDFStaticObserver%20%u7684%u6210%u5458%u53D8%u91CF_destroyingStatics%u6765%u5224%u65ADmongoDbMain%u7ED3%u675F%u3002%0A%09%20%20%20%20static%20StaticObserver%20staticObserver%3B%0A%0A%09%09%23if%20defined%28_WIN32%29%0A%09%20%20%20%20mongo%3A%3AreportEventToSystem%20%3D%20%26mongo%3A%3AreportEventToSystemImpl%3B%0A%09%09%23endif%0A%0A%09%20%20%20%20getcurns%20%3D%20ourgetns%3B%0A%0A%09%20%20%20%20setupSignalHandlers%28%29%3B%0A%0A%09%20%20%20%20dbExecCommand%20%3D%20argv%5B0%5D%3B%0A%0A%09%20%20%20%20srand%28curTimeMicros%28%29%29%3B%0A%09%20%20%20%20%7B%0A%09%09%20%20%20%20//%u5224%u65AD%u662F%u5426%u4E3A%u7CFB%u7EDF%u662F%u5426%u4E3A%u5C0F%u7AEF%u6A21%u5F0F%uFF0CMongoDB%u6682%u65F6%u4E0D%u652F%u6301%u5927%u7AEF%u6A21%u5F0F%u670D%u52A1%u5668%u3002%0A%09%20%20%20%20%20%20%20%20unsigned%20x%20%3D%200x12345678%3B%0A%09%20%20%20%20%20%20%20%20unsigned%20char%26%20b%20%3D%20%28unsigned%20char%26%29%20x%3B%0A%09%20%20%20%20%20%20%20%20if%20%28%20b%20%21%3D%200x78%20%29%20%7B%0A%09%20%20%20%20%20%20%20%20%20%20%20%20out%28%29%20%3C%3C%20%22big%20endian%20cpus%20not%20yet%20supported%22%20%3C%3C%20endl%3B%0A%09%20%20%20%20%20%20%20%20%20%20%20%20return%2033%3B%0A%09%20%20%20%20%20%20%20%20%7D%0A%09%20%20%20%20%7D%0A%0A%09%20%20%20%20if%28%20argc%20%3D%3D%201%20%29%0A%09%20%20%20%20%20%20%20%20cout%20%3C%3C%20dbExecCommand%20%3C%3C%20%22%20--help%20for%20help%20and%20startup%20options%22%20%3C%3C%20endl%3B%0A%09%09//%u4E3B%u8981%u89E3%u6790%u547D%u4EE4%u884C%uFF0C%u5176%u4E2D%u4F1A%u8BFB%u53D6%u914D%u7F6E%u6587%u4EF6%uFF0C%u5E76%u8D4B%u503C%u7ED9%u53D8%u91CF%uFF0C%u8FD9%u4E00%u5757%u8BBE%u8BA1%u6BD4%u8F83%u5DE7%u5999%uFF0C%u65E5%u540E%u53EF%u4EE5%u5355%u72EC%u5F00%u7BC7%u7814%u7A76%u3002%0A%09%20%20%20%20Status%20status%20%3D%20mongo%3A%3ArunGlobalInitializers%28argc%2C%20argv%2C%20envp%29%3B%0A%09%20%20%20%20if%20%28%21status.isOK%28%29%29%20%7B%0A%09%20%20%20%20%20%20%20%20severe%28%29%20%3C%3C%20%22Failed%20global%20initialization%3A%20%22%20%3C%3C%20status%3B%0A%09%20%20%20%20%20%20%20%20%3A%3A_exit%28EXIT_FAILURE%29%3B%0A%09%20%20%20%20%7D%0A%0A%09%20%20%20%20startupConfigActions%28std%3A%3Avector%3Cstd%3A%3Astring%3E%28argv%2C%20argv%20+%20argc%29%29%3B%0A%09%20%20%20%20cmdline_utils%3A%3AcensorArgvArray%28argc%2C%20argv%29%3B%0A%09%09//%u521D%u59CB%u5316%u670D%u52A1%u5668%u8BA4%u8BC1%u914D%u7F6E%0A%09%20%20%20%20if%20%28%21initializeServerGlobalState%28%29%29%0A%09%20%20%20%20%20%20%20%20%3A%3A_exit%28EXIT_FAILURE%29%3B%0A%0A%09%20%20%20%20//%u542F%u52A8%u4E00%u4E2A%u7EBF%u7A0B%u5904%u7406%u7CFB%u7EDF%u4FE1%u53F7%0A%09%20%20%20%20startSignalProcessingThread%28%29%3B%0A%09%09//%u5B9A%u65F6%u540C%u6B65%u6587%u4EF6%0A%09%20%20%20%20dataFileSync.go%28%29%3B%0A%0A%09%09%23if%20defined%28_WIN32%29%0A%09%20%20%20%20if%20%28ntservice%3A%3AshouldStartService%28%29%29%20%7B%0A%09%20%20%20%20%20%20%20%20ntservice%3A%3AstartService%28%29%3B%0A%09%20%20%20%20%20%20%20%20//%20exits%20directly%20and%20so%20never%20reaches%20here%20either.%0A%09%20%20%20%20%7D%0A%09%09%23endif%0A%09%09//%u8FDB%u884C%u4E00%u4E9B%u6D4B%u8BD5%0A%09%20%20%20%20StartupTest%3A%3ArunTests%28%29%3B%0A%09%20%20%20%20//%u521D%u59CB%u5316%u5404%u6A21%u5757%uFF0C%u5E76%u5F00%u59CB%u76D1%u542C%u5BA2%u6237%u7AEF%u8BF7%u6C42%uFF0C%u670D%u52A1%u7AEF%u5F00%u59CB%u8FD0%u884C%0A%09%20%20%20%20initAndListen%28serverGlobalParams.port%29%3B%0A%09%20%20%20%20dbexit%28EXIT_CLEAN%29%3B%0A%09%20%20%20%20return%200%3B%0A%09%7D%0A%20%0A%0AdataFileSync%u662FDataFileSync%u5BF9%u8C61%0A%0A%20%20%20%20class%20DataFileSync%20%3A%20public%20BackgroundJob%20%2C%20public%20ServerStatusSection%20%7B%0A%09public%3A%0A%09%09...%0A%09%09void%20run%28%29%20%7B%0A%09%09...%0A%09%7D%0A%0A%09void%20BackgroundJob%3A%3Ago%28%29%20%7B%0A%20%20%20%20%20%20%20%20scoped_lock%20l%28%20_status-%3Emutex%20%29%3B%0A%20%20%20%20%20%20%20%20massert%28%2017234%2C%20mongoutils%3A%3Astr%3A%3Astream%28%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%3C%20%22backgroundJob%20already%20running%3A%20%22%20%3C%3C%20name%28%29%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_status-%3Estate%20%21%3D%20Running%20%29%3B%0A%0A%20%20%20%20%20%20%20%20//%20If%20the%20job%20is%20already%20%27done%27%2C%20for%20instance%20because%20it%20was%20cancelled%20or%20already%0A%20%20%20%20%20%20%20%20//%20finished%2C%20ignore%20additional%20requests%20to%20run%20the%20job.%0A%20%20%20%20%20%20%20%20if%20%28_status-%3Estate%20%3D%3D%20NotStarted%29%20%7B%0A%09%20%20%20%20%20%20%20%20//BackgroundJob%3A%3AjobBody%u51FD%u6570%u4E2D%u6267%u884C%u5B50%u7C7Brun%u51FD%u6570%uFF0C%u6240%u4EE5%u6587%u4EF6%u540C%u6B65%u5C06%u5728%u540E%u53F0%u7EBF%u7A0B%u4E2D%u6267%u884C%u3002%0A%20%20%20%20%20%20%20%20%20%20%20%20boost%3A%3Athread%20t%28%20boost%3A%3Abind%28%20%26BackgroundJob%3A%3AjobBody%20%2C%20this%20%29%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20_status-%3Estate%20%3D%20Running%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0AClient%3A%3AinitThread%28...%29%u51FD%u6570%u5728%u4E4B%u540E%u5F88%u591A%u5730%u65B9%u8FD8%u4F1A%u7528%u5230%uFF0C%u6E90%u7801%u4E2D%u7684%u6CE8%u91CA%u662F%u201Ceach%20thread%20which%20does%20db%20operations%20has%20a%20Client%20object%20in%20TLS.%20%20call%20this%20when%20your%20thread%20starts.%u201D%0A%0A%20%20%20%20Client%26%20Client%3A%3AinitThread%28const%20char%20*desc%2C%20AbstractMessagingPort%20*mp%29%20%7B%0A%20%20%20%20%20%20%20%20verify%28%20currentClient.get%28%29%20%3D%3D%200%20%29%3B%0A%0A%20%20%20%20%20%20%20%20string%20fullDesc%20%3D%20desc%3B%0A%20%20%20%20%20%20%20%20if%20%28%20str%3A%3Aequals%28%20%22conn%22%20%2C%20desc%20%29%20%26%26%20mp%20%21%3D%20NULL%20%29%0A%20%20%20%20%20%20%20%20%20%20%20%20fullDesc%20%3D%20str%3A%3Astream%28%29%20%3C%3C%20desc%20%3C%3C%20mp-%3EconnectionId%28%29%3B%0A%09%09//%u8BBE%u7F6E%u7EBF%u7A0B%u540D%u79F0%uFF0C%u8BE5%u540D%u79F0%u4FDD%u5B58%u5728%u7EBF%u7A0B%u5168%u5C40%u53D8%u91CF_threadName%u4E2D%0A%20%20%20%20%20%20%20%20setThreadName%28%20fullDesc.c_str%28%29%20%29%3B%0A%0A%20%20%20%20%20%20%20%20//%20Create%20the%20client%20obj%2C%20attach%20to%20thread%0A%20%20%20%20%20%20%20%20Client%20*c%20%3D%20new%20Client%28%20fullDesc%2C%20mp%20%29%3B%0A%20%20%20%20%20%20%20%20currentClient.reset%28c%29%3B%0A%20%20%20%20%20%20%20%20mongo%3A%3AlastError.initThread%28%29%3B%0A%20%20%20%20%20%20%20%20c-%3EsetAuthorizationSession%28new%20AuthorizationSession%28new%20AuthzSessionExternalStateMongod%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20getGlobalAuthorizationManager%28%29%29%29%29%3B%0A%20%20%20%20%20%20%20%20return%20*c%3B%0A%20%20%20%20%7D%0A%u4E0A%u9762%u7684%u4EE3%u7801%u4E2DsetThreadName%28%29%2C%20currentClient.reset%28c%29%2C%20%20mongo%3A%3AlastError.initThread%28%29%u8FD9%u4E09%u4E2A%u5730%u65B9%u521A%u5F00%u59CB%u8BA9%u6211%u6BD4%u8F83%u7591%u60D1%uFF0C%u56E0%u4E3A_threadName%uFF0CcurrentClient%uFF0ClastError%u90FD%u662F%u5168%u5C40%u53D8%u91CF%uFF0C%u4F46%u662F%u6BCF%u4E2A%u7EBF%u7A0B%u90FD%u53BB%u8BBE%u7F6E%u4E00%u6B21%u662F%u4E0D%u662F%u4F1A%u6539%u53D8%u5176%u4ED6%u4E4B%u524D%u8BBE%u7F6E%u7684%u503C%u5462%uFF1F%u540E%u6765%u81EA%u4E60%u5206%u6790%u6E90%u7801%u540E%u53D1%u73B0%u4ED6%u4EEC%u90FD%u4F7F%u7528%u4E86%u7EBF%u7A0B%u672C%u5730%u5B58%u50A8%u6280%u672F%uFF0Cmongodb%u4E2D%u662F%u76F4%u63A5%u7528%20boost%3A%3Athread_specific_ptr%20%u6765%u5B9E%u73B0%uFF0C%u5728%u6BCF%u4E2A%u7EBF%u7A0B%u4E2D%uFF0C%u90FD%u5404%u81EAnew%u4E00%u4E2A%u5BF9%u8C61%u4EA4%u7ED9%u5168%u5C40%u7684threah_specific_ptr%u8FDB%u884C%u7BA1%u7406%uFF0C%u5F53%u7EBF%u7A0B%u9000%u51FA%u540E%uFF0C%u4ED6%u4F1A%u81EA%u52A8%u91CA%u653E%u8FD9%u4E2A%u5BF9%u8C61%u3002%0A%0A%u4E0B%u9762%u5BF9initAndListen%u51FD%u6570%u5355%u72EC%u8FDB%u884C%u5206%u6790%3A%0A%0A%20%20%20%20void%20initAndListen%28int%20listenPort%29%20%7B%09%0A%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20_initAndListen%28listenPort%29%3B%0A%20%20%20%20%20%20%20%20%7D%20%0A%20%20%20%20%20%20%20%20...%0A%20%20%20%20%7D%0A%0A%u4EE5%u4E0B%u662F%u5BF9_initAndListen%u4E3B%u8981%u4EE3%u7801%u7684%u5206%u6790%3A%0A%0A%09void%20_initAndListen%28int%20listenPort%20%29%20%7B%0A%20%20%20%20%20%20%20%20//%u8BBE%u7F6E%u7EBF%u7A0B%u540D%u79F0%uFF0C%u4E3A%u5F53%u524D%u7EBF%u7A0B%u521B%u5EFA%u6570%u636E%u5E93%u64CD%u4F5C%u7684Client%u5BF9%u8C61%0A%20%20%20%20%20%20%20%20Client%3A%3AinitThread%28%22initandlisten%22%29%3B%0A%09%09//%u5224%u65AD%u5F53%u524D%u662F%u5426%u4E3A32%u4F4D%u7CFB%u7EDF%0A%20%20%20%20%20%20%20%20bool%20is32bit%20%3D%20sizeof%28int*%29%20%3D%3D%204%3B%0A%09%09....%0A%20%20%20%20%20%20%20%20//%20Read%20storage%20engine%20metadata%20file%20%28introduced%20in%202.8%29%20if%20present.%0A%20%20%20%20%20%20%20%20//%20Do%20not%20start%20server%20if%20storage%20engine%20in%20metadata%20is%20not%20%27mmapv1%27.%0A%20%20%20%20%20%20%20%20StorageEngineMetadata%3A%3Avalidate%28storageGlobalParams.dbpath%2C%20%22mmapv1%22%29%3B%0A%0A%20%20%20%20%20%20%20%20//%20TODO%20check%20non-journal%20subdirs%20if%20using%20directory-per-db%0A%20%20%20%20%20%20%20%20checkReadAhead%28storageGlobalParams.dbpath%29%3B%0A%09%09//%u6587%u4EF6%u9501%0A%09%09//%u4FDD%u8BC1%u5F53%u524Ddbpath%u76EE%u5F55%u4E0B%u53EA%u6709%u4E00%u4E2Amongodb%u5B9E%u4F8B%uFF0C%u5982%u679C%u5F53%u524Ddbpath%u76EE%u5F55%u5DF2%u7ECF%u6709mongodb%u8FD0%u884C%0A%09%09//%u5219%u83B7%u53D6%u6587%u4EF6%u9501%u5931%u8D25%u3002%0A%20%20%20%20%20%20%20%20acquirePathLock%28mongodGlobalParams.repair%29%3B%0A%20%20%20%20%20%20%20%20//%u5220%u9664%u6240%u6709%u4E34%u65F6%u6587%u4EF6%0A%20%20%20%20%20%20%20%20boost%3A%3Afilesystem%3A%3Aremove_all%28storageGlobalParams.dbpath%20+%20%22/_tmp/%22%29%3B%0A%09%09//%u6587%u4EF6%0A%20%20%20%20%20%20%20%20FileAllocator%3A%3Aget%28%29-%3Estart%28%29%3B%0A%0A%20%20%20%20%20%20%20%20...%0A%0A%20%20%20%20%20%20%20%20MONGO_ASSERT_ON_EXCEPTION_WITH_MSG%28%20clearTmpFiles%28%29%2C%20%22clear%20tmp%20files%22%20%29%3B%0A%09%09//%u5F00%u542Fjournal%u7EBF%u7A0B%uFF0C%u521B%u5EFA%u6301%u4E45%u5316%u76EE%u5F55%u548C%u6587%u4EF6%0A%20%20%20%20%20%20%20%20dur%3A%3Astartup%28%29%3B%0A%20%20%20%20%20%20%20%20...%0A%09%09//%u521B%u5EFAv8%u811A%u672C%u5F15%u64CE%0A%20%20%20%20%20%20%20%20if%20%28mongodGlobalParams.scriptingEnabled%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20ScriptEngine%3A%3Asetup%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20globalScriptEngine-%3EsetCheckInterruptCallback%28%20jsInterruptCallback%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20globalScriptEngine-%3EsetGetCurrentOpIdCallback%28%20jsGetCurrentOpIdCallback%20%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20//%u542F%u52A8%u7EBF%u7A0B%u5FEB%u7167%uFF0C%u5B9A%u65F6%u62CD%u7167%uFF0C%u9ED8%u8BA44%u79D2%0A%20%20%20%20%20%20%20%20if%20%28serverGlobalParams.isHttpInterfaceEnabled%29%0A%20%20%20%20%20%20%20%20%20%20%20%20snapshotThread.go%28%29%3B%0A%0A%20%20%20%20%20%20%20%20d.clientCursorMonitor.go%28%29%3B%0A%20%20%20%20%20%20%20%20//%u62A5%u544A%u5185%u5B58%u4F7F%u7528%u60C5%u51B5%u548C%u8FC7%u65F6%u8FC7%u65F6%u5220%u9664%u5BA2%u6237%u7AEF%u6E38%u6807%u7684%u7EBF%u7A0B%0A%20%20%20%20%20%20%20%20PeriodicTask%3A%3AstartRunningPeriodicTasks%28%29%3B%0A%20%20%20%20%20%20%20%20//%u542F%u52A8%u5B9A%u671F%u6267%u884C%u4EFB%u52A1%u7684%u7EBF%u7A0B%uFF0C%u521B%u5EFAPeriodicTaskRunner%2C%u68C0%u6D4Bshutdown%u4FE1%u53F7%uFF0C%u6CA1%u6709%u5C31%u7B49%u5F85%uFF0C%u9ED8%u8BA460%u79D2%u3002%0A%20%20%20%20%20%20%20%20if%20%28missingRepl%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20a%20warning%20was%20logged%20earlier%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20startTTLBackgroundJob%28%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%09%23ifndef%20_WIN32%0A%20%20%20%20%20%20%20%20mongo%3A%3AsignalForkSuccess%28%29%3B%0A%09%23endif%0A%0A%20%20%20%20%20%20%20%20if%28getGlobalAuthorizationManager%28%29-%3EisAuthEnabled%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20open%20admin%20db%20in%20case%20we%20need%20to%20use%20it%20later.%20TODO%20this%20is%20not%20the%20right%20way%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20//%20resolve%20this.%0A%20%20%20%20%20%20%20%20%20%20%20%20Client%3A%3AWriteContext%20c%28%22admin%22%2C%20storageGlobalParams.dbpath%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20authindex%3A%3AconfigureSystemIndexes%28%22admin%22%29%3B%0A%0A%20%20%20%20%20%20%20%20getDeleter%28%29-%3EstartWorkers%28%29%3B%0A%0A%20%20%20%20%20%20%20%20//%20Starts%20a%20background%20thread%20that%20rebuilds%20all%20incomplete%20indices.%20%0A%20%20%20%20%20%20%20%20indexRebuilder.go%28%29%3B%20%0A%09%09//%u5F00%u59CB%u76D1%u542C%0A%20%20%20%20%20%20%20%20listen%28listenPort%29%3B%0A%0A%20%20%20%20%20%20%20%20//%20listen%28%29%20will%20return%20when%20exit%20code%20closes%20its%20socket.%0A%20%20%20%20%20%20%20%20exitCleanly%28EXIT_NET_ERROR%29%3B%0A%20%20%20%20%7D%0A%0A%u4ECE%u4E0A%u9762%u7684_initAndListen%u51FD%u6570%u4E2D%u53EF%u4EE5%u770B%u5230%uFF0C%u5E76%u6CA1%u6709%u5F00%u59CB%u76D1%u542C%u5BA2%u6237%u7AEF%u8BF7%u6C42%uFF0C%u53EA%u662F%u505A%u4E86%u4E00%u4E9B%u6570%u636E%u5E93%u51C6%u5907%u5DE5%u4F5C%uFF0C%u6700%u540E%u624D%u8C03%u7528listen%28listenPort%29%u51FD%u6570%u5BF9%u7AEF%u53E3%u8FDB%u884C%u76D1%u542C%uFF0C%u4E0B%u9762%u7EE7%u7EED%u5206%u6790listen%u51FD%u6570%uFF1A%0A%0A%20%20%20%20void%20listen%28int%20port%29%20%7B%0A%20%20%20%20%20%20%20%20//testTheDb%28%29%3B%0A%20%20%20%20%20%20%20%20MessageServer%3A%3AOptions%20options%3B%0A%20%20%20%20%20%20%20%20options.port%20%3D%20port%3B%0A%20%20%20%20%20%20%20%20options.ipList%20%3D%20serverGlobalParams.bind_ip%3B%0A%0A%20%20%20%20%20%20%20%20MessageServer%20*%20server%20%3D%20createServer%28%20options%20%2C%20new%20MyMessageHandler%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20server-%3EsetAsTimeTracker%28%29%3B%0A%20%20%20%20%20%20%20%20//%20we%20must%20setupSockets%20prior%20to%20logStartup%28%29%20to%20avoid%20getting%20too%20high%0A%20%20%20%20%20%20%20%20//%20a%20file%20descriptor%20for%20our%20calls%20to%20select%28%29%0A%20%20%20%20%20%20%20%20//%u521D%u59CB%u5316Socket%uFF0C%u7136%u540E%u8C03%u7528listen%u51FD%u6570%u5F00%u59CB%u76D1%u542C%0A%20%20%20%20%20%20%20%20server-%3EsetupSockets%28%29%3B%0A%0A%20%20%20%20%20%20%20%20logStartup%28%29%3B%0A%20%20%20%20%20%20%20%20//%u540E%u53F0%u542F%u52A8%u6570%u636E%u5206%u7247%u7EBF%u7A0B%0A%20%20%20%20%20%20%20%20startReplication%28%29%3B%0A%20%20%20%20%20%20%20%20//%u5982%u679C%u8BBE%u7F6E%u4E86--httpinterface%u53C2%u6570%uFF0C%u5219%u4F1A%u542F%u52A8web%u7EBF%u7A0B%u7EBF%u7A0B%u76D1%u542Chttp%u8BF7%u6C42%0A%20%20%20%20%20%20%20%20if%20%28serverGlobalParams.isHttpInterfaceEnabled%29%0A%20%20%20%20%20%20%20%20%20%20%20%20boost%3A%3Athread%20web%28%20boost%3A%3Abind%28%26webServerThread%2C%20new%20RestAdminAccess%28%29%20/*%20takes%20ownership%20*/%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20server-%3Erun%28%29%3B%0A%09%7D%0AMessageServer%20%u662F%u6D88%u606F%u670D%u52A1%u7684%u57FA%u7C7B%uFF0CcreateServer%u8FD4%u56DE%u7684%u662F%u4ED6%u7684%u5B50%u7C7BPortMessageServer%u7684%u5BF9%u8C61%uFF0CPortMessageServer%u4E2D%u91CD%u5199%u4E86%u865A%u51FD%u6570run%uFF0C%u5BA2%u6237%u7AEF%u8FDE%u63A5%u5904%u7406%u53C8%u88AB%u5EF6%u8FDF%u5230%u4E86PortMessageServer%3A%3Arun%28%29%u51FD%u6570%u4E2D%u3002%0A%0A%20%20%20%20class%20MessageServer%20%7B%0A%20%20%20%20public%3A%0A%20%20%20%20%20%20%20%20struct%20Options%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20int%20port%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20port%20to%20bind%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20string%20ipList%3B%20%20%20%20%20%20%20%20%20%20%20%20%20//%20addresses%20to%20bind%20to%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Options%28%29%20%3A%20port%280%29%2C%20ipList%28%22%22%29%20%7B%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%0A%20%20%20%20%20%20%20%20virtual%20%7EMessageServer%28%29%20%7B%7D%0A%20%20%20%20%20%20%20%20virtual%20void%20run%28%29%20%3D%200%3B%0A%20%20%20%20%20%20%20%20virtual%20void%20setAsTimeTracker%28%29%20%3D%200%3B%0A%20%20%20%20%20%20%20%20virtual%20void%20setupSockets%28%29%20%3D%200%3B%0A%20%20%20%20%7D%3B%0A%20%20%20%20%0A%20%20%20%20class%20Listener%20%3A%20boost%3A%3Anoncopyable%20%7B%0A%20%20%20%20public%3A%0A%20%20%20%20%20%20%20%20void%20initAndListen%28%29%3B%20//%20never%20returns%20unless%20error%20%28start%20a%20thread%29%0A%0A%20%20%20%20%20%20%20%20/*%20spawn%20a%20thread%2C%20etc.%2C%20then%20return%20*/%0A%20%20%20%20%20%20%20%20virtual%20void%20accepted%28boost%3A%3Ashared_ptr%3CSocket%3E%20psocket%2C%20long%20long%20connectionId%20%29%3B%0A%20%20%20%20%20%20%20%20virtual%20void%20acceptedMP%28MessagingPort%20*mp%29%3B%0A%20%20%20%20%20%20%20%20...%0A%20%20%20%20%7D%0A%0A%20%20%20%20%20class%20PortMessageServer%20%3A%20public%20MessageServer%20%2C%20public%20Listener%20%7B%0A%09%09...%0A%09%7D%0A%0A%u4E0B%u9762%u7EE7%u7EED%u5206%u6790PortMessageServer%3A%3Arun%28%29%u51FD%u6570%3A%0A%0A%20%20%20%20void%20run%28%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20initAndListen%28%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%u7531%u4E8EinitAndListen%u51FD%u6570%u5728mongodb%u4E2DWindows%u548CLinux%u4E24%u90E8%u5206%u5206%u5F00%u6765%u5B9E%u73B0%uFF0C%u6211%u4EEC%u53EA%u5206%u6790Linux%u90E8%u5206%uFF0C%u4E24%u90E8%u5206%u539F%u6765%u76F8%u540C%uFF0C%u90FD%u662F%u4F7F%u7528select%u6765%u76D1%u542C%u5BA2%u6237%u7AEF%u8BF7%u6C42%u3002%u4E0B%u9762%u4EE3%u7801%u6211%u5220%u9664%u90E8%u5206%uFF0C%u53EA%u4FDD%u7559%u5904%u7406%u903B%u8F91%u3002%0A%0A%20%20%20%20%23if%20%21defined%28_WIN32%29%0A%20%20%20%20void%20Listener%3A%3AinitAndListen%28%29%20%7B%0A%20%20%20%20%20%20%20%20if%20%28%21_setupSocketsSuccessful%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20SOCKET%20maxfd%20%3D%200%3B%20//%20needed%20for%20select%28%29%0A%20%20%20%20%20%20%20%20for%20%28unsigned%20i%20%3D%200%3B%20i%20%3C%20_socks.size%28%29%3B%20i++%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28_socks%5Bi%5D%20%3E%20maxfd%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxfd%20%3D%20_socks%5Bi%5D%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20struct%20timeval%20maxSelectTime%3B%0A%20%20%20%20%20%20%20%20while%20%28%20%21%20inShutdown%28%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20fd_set%20fds%5B1%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20FD_ZERO%28fds%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20%28vector%3CSOCKET%3E%3A%3Aiterator%20it%3D_socks.begin%28%29%2C%20end%3D_socks.end%28%29%3B%20it%20%21%3D%20end%3B%20++it%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20FD_SET%28*it%2C%20fds%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20maxSelectTime.tv_sec%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxSelectTime.tv_usec%20%3D%2010000%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20int%20ret%20%3D%20select%28maxfd+1%2C%20fds%2C%20NULL%2C%20NULL%2C%20%26maxSelectTime%29%3B%0A%09%09%09...%0A%09%09%09%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20%28vector%3CSOCKET%3E%3A%3Aiterator%20it%3D_socks.begin%28%29%2C%20end%3D_socks.end%28%29%3B%20it%20%21%3D%20end%3B%20++it%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%21%20%28FD_ISSET%28*it%2C%20fds%29%29%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20SockAddr%20from%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20int%20s%20%3D%20accept%28*it%2C%20from.raw%28%29%2C%20%26from.addressSize%29%3B%0A%09%09%09%09...%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20long%20long%20myConnectionNumber%20%3D%20globalConnectionNumber.addAndFetch%281%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20boost%3A%3Ashared_ptr%3CSocket%3E%20pnewSock%28%20new%20Socket%28s%2C%20from%29%20%29%3B%0A%09%23ifdef%20MONGO_SSL%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28_ssl%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pnewSock-%3EsecureAccepted%28_ssl%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%09%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20accepted%28%20pnewSock%20%2C%20myConnectionNumber%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%09%23else%20%0A%u4E0A%u9762%u662F%u4E00%u4E2A%u6807%u51C6%u7684%u670D%u52A1%u7AEFsocket%20select%u6A21%u578B%uFF0C%u6BCF%u5F53%u6709%u5BA2%u6237%u7AEFsocket%u8FDE%u63A5%u65F6%uFF0Caccept%u6210%u529F%u540E%u8C03%u7528accepted%u51FD%u6570%u5904%u7406%u3002%0A%0A%20%20%20%20void%20Listener%3A%3Aaccepted%28boost%3A%3Ashared_ptr%3CSocket%3E%20psocket%2C%20long%20long%20connectionId%20%29%20%7B%0A%20%20%20%20%20%20%20%20MessagingPort*%20port%20%3D%20new%20MessagingPort%28psocket%29%3B%0A%20%20%20%20%20%20%20%20port-%3EsetConnectionId%28%20connectionId%20%29%3B%0A%20%20%20%20%20%20%20%20acceptedMP%28%20port%20%29%3B%0A%20%20%20%20%7D%0A%u6B64%u5904%u8C03%u7528%u7684PortMessageServer%u5BF9%u8C61%u7684acceptedMP%u6210%u5458%u51FD%u6570%28PortMessageServer%u662FListener%u7684%u5B50%u7C7B%29%uFF0C%u8FD9%u91CC%u6211%u4EEC%u770B%u5230%u4E86%u4E00%u4E2A%u65B0%u7684%u7C7BMessagingPort%uFF0CMessagingPort%u5C01%u88C5%u4E86Message%u7684%u53D1%u9001%u3001%u63A5%u6536%u7B49%u64CD%u4F5C%uFF0C%u82E5%u6709%u9700%u6C42%u4EE5%u540E%u518D%u5177%u4F53%u5206%u6790%u3002%0A%0A%20%20%20%20virtual%20void%20acceptedMP%28MessagingPort%20*%20p%29%20%7B%0A%09%20%20%20%20...%0A%20%20%20%20%20%20%20%20pthread_attr_t%20attrs%3B%0A%20%20%20%20%20%20%20%20pthread_attr_init%28%26attrs%29%3B%0A%20%20%20%20%20%20%20%20pthread_attr_setdetachstate%28%26attrs%2C%20PTHREAD_CREATE_DETACHED%29%3B%0A%0A%20%20%20%20%20%20%20%20static%20const%20size_t%20STACK_SIZE%20%3D%201024*1024%3B%20//%20if%20we%20change%20this%20we%20need%20to%20update%20the%20warning%0A%0A%20%20%20%20%20%20%20%20struct%20rlimit%20limits%3B%0A%20%20%20%20%20%20%20%20pthread_t%20thread%3B%0A%20%20%20%20%20%20%20%20HandleIncomingMsgParam*%20himParam%20%3D%20new%20HandleIncomingMsgParam%28p%2C%20_handler%29%3B%0A%20%20%20%20%20%20%20%20int%20failed%20%3D%20pthread_create%28%26thread%2C%20%26attrs%2C%20%26handleIncomingMsg%2C%20himParam%29%3B%0A%0A%20%20%20%20%20%20%20%20pthread_attr_destroy%28%26attrs%29%3B%0A%20%20%20%20%7D%0AacceptedMP%u63A5%u6536%u5230%u6D88%u606F%u540E%u5EFA%u7ACB%u4E00%u4E2A%u540E%u53F0%u7EBF%u7A0B%uFF0C%u5728%u540E%u53F0%u7EBF%u7A0B%u4E2D%u6267%u884ChandleIncomingMsg%u51FD%u6570%uFF0C%u5904%u7406%u5BA2%u6237%u7AEF%u8FDE%u63A5%u3002%0A%0A%20%20%20%20%20%20static%20void*%20handleIncomingMsg%28void*%20arg%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20TicketHolderReleaser%20connTicketReleaser%28%20%26Listener%3A%3AglobalTicketHolder%20%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20scoped_ptr%3CHandleIncomingMsgParam%3E%20himArg%28static_cast%3CHandleIncomingMsgParam*%3E%28arg%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20MessagingPort*%20inPort%20%3D%20himArg-%3EinPort%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20MessageHandler*%20handler%20%3D%20himArg-%3Ehandler%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20inPort-%3Epsock-%3EsetLogLevel%28logger%3A%3ALogSeverity%3A%3ADebug%281%29%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20scoped_ptr%3CMessagingPort%3E%20p%28%20inPort%20%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20string%20otherSide%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Message%20m%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LastError%20*%20le%20%3D%20new%20LastError%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lastError.reset%28%20le%20%29%3B%20//%20lastError%20now%20has%20ownership%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handler-%3Econnected%28%20p.get%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20%28%20%21%20inShutdown%28%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20m.reset%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20p-%3Epsock-%3EclearCounters%28%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28%20%21%20p-%3Erecv%28m%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20handler-%3Eprocess%28%20m%20%2C%20p.get%28%29%20%2C%20le%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20networkCounter.hit%28%20p-%3Epsock-%3EgetBytesIn%28%29%20%2C%20p-%3Epsock-%3EgetBytesOut%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20handler-%3Edisconnected%28%20p.get%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20NULL%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%3B%0A%0A%u4EE5%u4E0A%u4EE3%u7801%u53EF%u4EE5%u770B%u51FA%uFF0C%u670D%u52A1%u7AEF%u5728%u63A5%u6536%u5230%u5BA2%u6237%u7AEF%u8FDE%u63A5%u8BF7%u6C42%u540E%u5EFA%u7ACB%u8FDE%u63A5%uFF0C%u7136%u540E%u521B%u5EFA%u540E%u53F0%u7EBF%u7A0B%uFF0C%u5728%u7EBF%u7A0B%u4E2D%u4F7F%u7528while%u5FAA%u73AF%u4E0D%u65AD%u7684%u63A5%u6536Message%uFF0C%u7136%u540E%u8C03%u7528handler%u7684process%u5904%u7406%u3002handler-%3Econnected%u91CC%u9762%u53EA%u662F%u518D%u6B21%u8C03%u7528Client%3A%3AinitThread%28%22conn%22%2C%20p%29%uFF0C%u8FD9%u4E2A%u95EE%u9898%u4E4B%u524D%u5DF2%u7ECF%u5206%u6790%u8FC7%u3002%0A%u6700%u540E%u4E00%u4E2A%u95EE%u9898%uFF0Chandler%u5BF9%u8C61%u5176%u5B9E%u5C31%u662FcreateServer%u65F6%u5019%u4F20%u5165%u7684%u7B2C%u4E8C%u4E2A%u53C2%u6570new%20MyMessageHandler%28%29%3B%0A%0A%20%20%20%20class%20MessageHandler%20%7B%0A%20%20%20%20public%3A%0A%20%20%20%20%20%20%20%20virtual%20%7EMessageHandler%28%29%20%7B%7D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20called%20once%20when%20a%20socket%20is%20connected%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20virtual%20void%20connected%28%20AbstractMessagingPort*%20p%20%29%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20called%20every%20time%20a%20message%20comes%20in%0A%20%20%20%20%20%20%20%20%20*%20handler%20is%20responsible%20for%20responding%20to%20client%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20virtual%20void%20process%28%20Message%26%20m%20%2C%20AbstractMessagingPort*%20p%20%2C%20LastError%20*%20err%20%29%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20/**%0A%20%20%20%20%20%20%20%20%20*%20called%20once%20when%20a%20socket%20is%20disconnected%0A%20%20%20%20%20%20%20%20%20*/%0A%20%20%20%20%20%20%20%20virtual%20void%20disconnected%28%20AbstractMessagingPort*%20p%20%29%20%3D%200%3B%0A%20%20%20%20%7D%3B%0A%0A%20%20%20%20%20class%20MyMessageHandler%20%3A%20public%20MessageHandler%20%7B%0A%09%09%20%20%20%20%20...%0A%20%20%20%20%7D%0A%0A%u81F3%u6B64mongod%u7684%u6574%u4E2A%u6D88%u606F%u5904%u7406%u8F6E%u5ED3%u5DF2%u7ECF%u51FA%u6765%u4E86%uFF0C%u5176%u4ED6%u7684%u90E8%u5206%u5C06%u4F1A%u5728%u540E%u7EED%u7684%u90E8%u5206%u4E2D%u7EE7%u7EED%u5206%u6790

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-83604-1-1.html 上篇帖子: MongoDB工具最新进展 下篇帖子: Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表