对ListenSocket 的研究(四)
磨砺技术珠矶,践行数据之道,追求卓越价值
回到上一级页面:PostgreSQL内部结构与源代码研究索引页 回到顶级页面:PostgreSQL索引页
[作者:高健@博客园 luckyjackgao@gmail.com]
对postmaster.c 中的 readmask,rmask,nsocket等进行分析,可以看到:它们之间有如下的关系(与细节无关的代码省略):
/*
* Initialise the masks for select() for the ports we are listening on.
* Return the number of sockets to listen on.
*/
static int
initMasks(fd_set *rmask)
{
int maxsock = -1;
int i;
FD_ZERO(rmask);
for (i = 0; i < MAXLISTEN; i++)
{
int fd = ListenSocket[i];
if (fd == PGINVALID_SOCKET)
break;
FD_SET(fd, rmask);
if (fd > maxsock)
maxsock = fd;
}
return maxsock + 1;
}
和
static int
ServerLoop(void)
{
......
nSockets = initMasks(&readmask);
for (;;)
{
fd_set rmask;
int selres;
/*
* Wait for a connection request to arrive.
* We wait at most one minute, to ensure that the other background
* tasks handled below get done even when no requests are arriving.
* If we are in PM_WAIT_DEAD_END state, then we don't want to accept
* any new connections, so we don't call select() at all; just sleep
* for a little bit with signals unblocked.
*/
memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set));
PG_SETMASK(&UnBlockSig);
if (pmState == PM_WAIT_DEAD_END)
{
...
}
else
{
...
selres = select(nSockets, &rmask, NULL, NULL, &timeout);
}
/*
* Block all signals until we wait again. (This makes it safe for our
* signal handlers to do nontrivial work.)
*/
PG_SETMASK(&BlockSig);
/* Now check the select() result */
if (selres < 0)
{
...
}
/*
* New connection pending on any of our sockets? If so, fork a child
* process to deal with it.
*/
if (selres > 0)
{
...
}
...
}
}
可以看出来,nsocket就是用于监听网络通信的地 fd_set中的文件描述符最大值+1。
至于原始的文件描述符,就是来自于 ListenSocket数组。
为了进一步研究,还需要从源头上看ListenSocket是如何被赋值的。
[作者:高健@博客园 luckyjackgao@gmail.com]
回到上一级页面:PostgreSQL内部结构与源代码研究索引页 回到顶级页面:PostgreSQL索引页
磨砺技术珠矶,践行数据之道,追求卓越价值