int registerFileDescForAsyncConn(int 		 			  fd,
                                 uint32_t				  actionmask_afterconn,
                                 AsyncCommBufferHandlers  methods_afterconn,
                                 void				     *userdata_afterconn,
                                 AsyncCommBuffer		 *newcommbuffer_afterconn)
{
    AsyncCommBufferHandlerUser userdata = NULL;
    userdata = rm_palloc0(AsyncCommContext,
                          sizeof(AsyncCommBufferHandlerUserData));
    userdata->ActionMaskForAfterConn = actionmask_afterconn;
    userdata->UserDataForAfterConn   = userdata_afterconn;
    userdata->MethodsForAfterConn	 = methods_afterconn;

    elog(DEBUG3, "Created AsyncComm Conn context.");

    int res = registerFileDesc(fd,
                               ASYNCCOMM_WRITE,
                               &AsyncCommBufferHandlersConn,
                               userdata,
                               newcommbuffer_afterconn);
    if ( res != FUNC_RETURN_OK )
    {
        elog(WARNING, "Fail to register communication in asynchronous connection "
             "progress.");
        rm_pfree(AsyncCommContext, userdata);
    }

    elog(DEBUG3, "Registered AsyncComm FD %d", fd);

    return res;
}
void ReadReadyHandler_MsgServer(AsyncCommBuffer buffer)
{
	int					res				= FUNC_RETURN_OK;
	ConnectionTrack 	newtrack 		= NULL;
	ConnectionTrackData tmptrackdata;
	AsyncCommBuffer     newcommbuffer   = NULL;
	struct sockaddr_in	clientaddr;
	socklen_t			clientaddrlen	= sizeof(clientaddr);
	int					fd				= -1;

	/* Always accept the connection. */
	fd = accept(buffer->FD, (struct sockaddr *)&clientaddr, &clientaddrlen);
	if ( fd == -1 )
	{
		elog(WARNING, "Resource manager socket accept error is detected. errno %d",
					  errno);
		return;
	}

	/* Create AsyncComm Message handler instance. */
	AsyncCommMessageHandlerContext context = createConnTrackHandlerContext();

	/* Add new client fd into AsyncComm manager. */
	res = registerFileDesc(fd,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		Assert(newcommbuffer == NULL);
		/* close the connection and cleanup. */
		closeConnectionRemote(&fd);
		rm_pfree(AsyncCommContext, context);
		return;
	}

	assignFileDescClientAddressInfo(newcommbuffer,
									NULL,
									0,
									&clientaddr,
									clientaddrlen);

	/* Let context able to track comm buffer. */
	context->AsyncBuffer = newcommbuffer;

	/* Call callback function to initialize context for message handlers. */
	InitHandler_Message(newcommbuffer);

	elog(DEBUG3, "Resource manager accepted one client connected from "
				 "%s:%d as FD %d.\n",
				 newcommbuffer->ClientAddrDotStr,
				 newcommbuffer->ClientAddrPort,
				 newcommbuffer->FD);
}
int  initializeSocketServer_RMSEG(void)
{
	int 		res		= FUNC_RETURN_OK;
	int 		netres 	= 0;
	char 	   *allip   = "0.0.0.0";
	pgsocket 	RMListenSocket[HAWQRM_SERVER_PORT_COUNT];

	for ( int i = 0 ; i < HAWQRM_SERVER_PORT_COUNT ; ++i ) {
		RMListenSocket[i] = PGINVALID_SOCKET;
	}

	/* Listen normal socket addresses. */
	netres = StreamServerPort( AF_UNSPEC,
							   allip,
							   rm_segment_port,
							   NULL,
							   RMListenSocket,
							   HAWQRM_SERVER_PORT_COUNT);

	/* If there are multiple segments in one host, which is common in old imp.
	 * We can not make all segments work. So, if HAWQ RM SEG fails to start
	 * socket server by listening the port, we accept this case and make it
	 * silent. HAWQ RM will not recognize this segment and will not assign
	 * tasks. */
	if ( netres != STATUS_OK ) {
		res = REQUESTHANDLER_FAIL_START_SOCKET_SERVER;
		elog( LOG,  "Can not create socket server. HostName=%s, Port=%d",
				    allip,
					rm_segment_port);
		return res;
	}

	/* Initialize array for polling all file descriptors. */
	initializeAsyncComm();
	int 			validfdcount = 0;
	AsyncCommBuffer newbuffer    = NULL;
	for ( int i = 0 ; i < HAWQRM_SERVER_PORT_COUNT ; ++i ) {
		if (RMListenSocket[i] != PGINVALID_SOCKET) {
			netres = registerFileDesc(RMListenSocket[i],
									  NULL,
									  ASYNCCOMM_READ,
									  &AsyncCommBufferHandlersMsgServer,
									  NULL,
									  &newbuffer);
			if ( netres != FUNC_RETURN_OK ) {
				res = REQUESTHANDLER_FAIL_START_SOCKET_SERVER;
				elog(LOG, "Resource manager cannot track socket server.");
				break;
			}
			validfdcount++;

			InitHandler_Message(newbuffer);
		}
	}

	if ( res != FUNC_RETURN_OK ) {
		for ( int i = 0 ; i < HAWQRM_SERVER_PORT_COUNT ; ++i ) {
			if ( RMListenSocket[i] != PGINVALID_SOCKET ) close(RMListenSocket[i]);
		}
		return res;
	}

	elog(DEBUG5, "HAWQ RM SEG :: Starts accepting resource request. "
				 "Listening normal socket port %s:%d. "
				 "Total listened %d FDs.",
				allip,
				rm_segment_port,
				validfdcount);
	return res;

}
int callSyncRPCDomain(const char     	   *sockfile,
					  const char 	 	   *sendbuff,
		        	  int   		  		sendbuffsize,
					  uint16_t		  		sendmsgid,
					  uint16_t 		  		exprecvmsgid,
					  SelfMaintainBuffer 	recvsmb)
{
	static char            			dfilename[1024];
	int 							fd 			  = -1;
	int 							res 		  = FUNC_RETURN_OK;
	AsyncCommBuffer					newcommbuffer = NULL;
	AsyncCommMessageHandlerContext 	context 	  = NULL;
	SyncRPCContextData 				userdata;

	/* Connect to the server side. */
	res = connectToServerDomain(sockfile, 0, &fd, 0, dfilename);
	if ( res != FUNC_RETURN_OK )
	{
		elog(WARNING, "Fail to connect to domain socket server %s, result %d",
				  sockfile,
				  res);
		goto exit;
	}

	initializeSyncRPContent(&userdata, recvsmb, exprecvmsgid);
	context = createMessageHandlerContext(&userdata);

	res = registerFileDesc(fd,
						   dfilename,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		rm_pfree(AsyncCommContext, context);
		elog(WARNING, "Fail to register FD for synchronous communication. %d", res);
		goto exit;
	}

	buildMessageToCommBuffer(newcommbuffer,
							 sendbuff,
							 sendbuffsize,
							 sendmsgid,
							 0,
							 0);
	context->AsyncBuffer = newcommbuffer;

	InitHandler_Message(newcommbuffer);

	/* Wait for the complete of the communication. */
	while( true )
	{
		processAllCommFileDescs();
		if ( userdata.CommStatus == SYNC_RPC_COMM_IDLE )
		{
			break;
		}
		else if ( QueryCancelPending )
		{
			/*
			 * We find that this QD wants to cancel the query, we don't need
			 * to continue the communication.
			 */
			res = TRANSCANCEL_INPROGRESS;
			break;
		}
	}

	res = res == TRANSCANCEL_INPROGRESS ? res : userdata.Result;

	/* Close and cleanup */
	closeAndRemoveAllRegisteredFileDesc();

	if (res != FUNC_RETURN_OK)
	{
	  elog(WARNING, "Sync RPC framework (domain) finds exception raised.");
	}
	return res;
exit:
	closeConnectionDomain(&fd, dfilename);
	return res;
}
int callSyncRPCRemote(const char     	   *hostname,
					  uint16_t              port,
		  	  	  	  const char 	 	   *sendbuff,
					  int   		  		sendbuffsize,
					  uint16_t		  		sendmsgid,
					  uint16_t 		  		exprecvmsgid,
					  SelfMaintainBuffer 	recvsmb,
					  char				   *errorbuf,
					  int					errorbufsize)
{
	int 							fd 			  = -1;
	int 							res 		  = FUNC_RETURN_OK;
	AsyncCommBuffer					newcommbuffer = NULL;
	AsyncCommMessageHandlerContext 	context 	  = NULL;
	SyncRPCContextData 				userdata;

	/* Connect to the server side. */
	res = connectToServerRemote(hostname, port, &fd);
	if ( res != FUNC_RETURN_OK )
	{
		snprintf(errorbuf, errorbufsize,
				 "failed to connect to remote socket server %s:%d",
				 hostname,
				 port);
		elog(WARNING, "%s", errorbuf);
		goto exit;
	}

	initializeSyncRPContent(&userdata, recvsmb, exprecvmsgid);
	context = createMessageHandlerContext(&userdata);

	res = registerFileDesc(fd,
						   NULL,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		rm_pfree(AsyncCommContext, context);

		snprintf(errorbuf, errorbufsize,
				 "failed to register socket connection fd %d connected to %s:%d "
				 "for resource rpc communication",
				 fd,
				 hostname, port);

		elog(WARNING, "%s", errorbuf);
		goto exit;
	}

	buildMessageToCommBuffer(newcommbuffer,
							 sendbuff,
							 sendbuffsize,
							 sendmsgid,
							 0,
							 0);

	context->AsyncBuffer = newcommbuffer;

	InitHandler_Message(newcommbuffer);

	/* Wait for the complete of the communication. */
	while( true )
	{
		processAllCommFileDescs();
		if ( userdata.CommStatus == SYNC_RPC_COMM_IDLE )
		{
			break;
		}
		else if ( QueryCancelPending )
		{
			/*
			 * We find that this QD wants to cancel the query, we don't need
			 * to continue the communication.
			 */
			res = TRANSCANCEL_INPROGRESS;
			break;
		}
	}

	res = res == TRANSCANCEL_INPROGRESS ? res : userdata.Result;

	/* Close and cleanup */
	closeAndRemoveAllRegisteredFileDesc();

	if (res != FUNC_RETURN_OK)
	{
	  elog(WARNING, "Sync RPC framework (inet) finds exception raised.");

	  switch(res)
	  {
	  case COMM2RM_CLIENT_FAIL_SEND:
		  snprintf(errorbuf, errorbufsize, "failed to send content");
		  break;
	  case COMM2RM_CLIENT_FAIL_RECV:
		  snprintf(errorbuf, errorbufsize, "failed to receive content");
		  break;
	  case REQUESTHANDLER_WRONGMESSAGE:
		  snprintf(errorbuf, errorbufsize, "wrong message was received");
		  break;
	  default:
		  Assert(false);
	  }
	}
	return res;
exit:
	elog(LOG, "Close fd %d at once", fd);
	closeConnectionRemote(&fd);
	return res;
}