提交 7880e63d 编写于 作者: E Enrico Giordani

[Fix] Duplicated sockets need to be closed properly.

If the child process exists without closing the socket first, a socket read
error occurs on both the parent process and the connected slave.
上级 aa69521d
......@@ -143,6 +143,23 @@ BOOL FDAPI_WSAGetOverlappedResult(int rfd, LPWSAOVERLAPPED lpOverlapped, LPDWORD
return SOCKET_ERROR;
}
/* This method should only be called to close the sockets duplicated
* by the child process.
*/
BOOL FDAPI_CloseDuplicatedSocket(int rfd) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
if (socket != INVALID_SOCKET) {
RFDMap::getInstance().removeRFDToSocketInfo(rfd);
RFDMap::getInstance().removeSocketToRFD(socket);
return f_closesocket(socket);
}
} CATCH_AND_REPORT();
errno = EBADF;
return FALSE;
}
int FDAPI_WSADuplicateSocket(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo) {
try {
SOCKET socket = RFDMap::getInstance().lookupSocket(rfd);
......
......@@ -199,6 +199,7 @@ int FDAPI_WSAIoctl(int rfd, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD
int FDAPI_WSASend(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
int FDAPI_WSARecv(int rfd, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
BOOL FDAPI_WSAGetOverlappedResult(int rfd, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags);
BOOL FDAPI_CloseDuplicatedSocket(int rfd);
int FDAPI_WSADuplicateSocket(int rfd, DWORD dwProcessId, LPWSAPROTOCOL_INFO lpProtocolInfo);
int FDAPI_WSASocket(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags);
int FDAPI_WSAGetLastError(void);
......
......@@ -363,6 +363,12 @@ BOOL QForkChildInit(HANDLE QForkControlMemoryMapHandle, DWORD ParentProcessID) {
g_pQForkControl->globalData.numfds,
g_pQForkControl->globalData.clientids,
pipe_write_fd);
// After the socket replication has finished, close the duplicated sockets.
// Failing to close the sockets properly will produce a socket read error
// on both the parent process and the slave.
for (int i = 0; i < g_pQForkControl->globalData.numfds; i++) {
FDAPI_CloseDuplicatedSocket(g_pQForkControl->globalData.fds[i]);
}
} else {
throw runtime_error("unexpected operation type");
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册