Ejemplo n.º 1
0
/**
 * Function to process the pollout
 *
 * @param fd
 *
 * @return NCSCC_RC_SUCCESS
 * @return NCSCC_RC_FAILURE
 *
 */
uint32_t dtm_intranode_process_pollout(int fd)
{
	DTM_INTRANODE_PID_INFO *pid_node = NULL;
	pid_node = dtm_intranode_get_pid_info_using_fd(fd);
	if (NULL == pid_node) {
		LOG_ER("DTM INTRA: PID info coressponding to fd doesnt exist, database mismatch. fd :%d",fd);
		osafassert(0);
		return NCSCC_RC_FAILURE;
	} else {
		/* Get the unsent messages from the list and send them */
		DTM_INTRANODE_UNSENT_MSGS *hdr = pid_node->msgs_hdr;
		if (NULL == hdr) {
			/* No messages to be sent, reset the POLLOUT event on this fd */
			dtm_intranode_reset_poll_fdlist(fd);
		} else {
			dtm_intranode_snd_unsent_msg(pid_node, fd);
		}
	}
	return NCSCC_RC_SUCCESS;
}
Ejemplo n.º 2
0
/**
 * Function to process intranode poll and rcv message
 *
 *
 *
 */
void dtm_intranode_process_poll_rcv_msg(int fd)
{
	DTM_INTRANODE_PID_INFO *node = NULL;

	node = dtm_intranode_get_pid_info_using_fd(fd);

	if (NULL == node) {
		LOG_ER("DTM INTRA : PID info coressponding to fd doesnt exist, database mismatch. fd :%d",fd);
		osafassert(0);
	}
	if (0 == node->bytes_tb_read) {
		if (0 == node->num_by_read_for_len_buff) {
			uint8_t *data;
			int recd_bytes = 0;

			/*******************************************************/
			/* Receive all incoming data on this socket */
			/*******************************************************/

			recd_bytes = recv(fd, node->len_buff, 2, 0);
			if (0 == recd_bytes) {
				TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
				dtm_intranode_process_pid_down(fd);
				dtm_intranode_del_poll_fdlist(fd);
				return;
			} else if (2 == recd_bytes) {
				uint16_t local_len_buf = 0;

				data = node->len_buff;
				local_len_buf = ncs_decode_16bit(&data);
				node->buff_total_len = local_len_buf;
				node->num_by_read_for_len_buff = 2;

				if (NULL == (node->buffer = calloc(1, (local_len_buf + 3)))) {
					/* Length + 2 is done to reuse the same buffer 
					   while sending to other nodes */
					LOG_ER("Memory allocation failed in dtm_intranode_processing");
					return;
				}
				recd_bytes = recv(fd, &node->buffer[2], local_len_buf, 0);

				if (recd_bytes < 0) {
					return;
				} else if (0 == recd_bytes) {
					TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
					dtm_intranode_process_pid_down(fd);
					dtm_intranode_del_poll_fdlist(fd);
					return;
				} else if (local_len_buf > recd_bytes) {
					/* can happen only in two cases, system call interrupt or half data, */
					TRACE("less data recd, recd bytes = %d, actual len = %d", recd_bytes,
					       local_len_buf);
					node->bytes_tb_read = node->buff_total_len - recd_bytes;
					return;
				} else if (local_len_buf == recd_bytes) {
					/* Call the common rcv function */
					dtm_intranode_process_poll_rcv_msg_common(node);
				} else {
					osafassert(0);
				}
			} else {
				/* we had recd some bytes */
				if (recd_bytes < 0) {
					/* This can happen due to system call interrupt */
					return;
				} else if (1 == recd_bytes) {
					/* We recd one byte of the length part */
					node->num_by_read_for_len_buff = recd_bytes;
				} else {
					osafassert(0);
				}
			}
		} else if (1 == node->num_by_read_for_len_buff) {
			int recd_bytes = 0;

			recd_bytes = recv(fd, &node->len_buff[1], 1, 0);
			if (recd_bytes < 0) {
				/* This can happen due to system call interrupt */
				return;
			} else if (1 == recd_bytes) {
				/* We recd one byte(remaining) of the length part */
				uint8_t *data = node->len_buff;
				node->num_by_read_for_len_buff = 2;
				node->buff_total_len = ncs_decode_16bit(&data);
				return;
			} else if (0 == recd_bytes) {
				TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
				dtm_intranode_process_pid_down(fd);
				dtm_intranode_del_poll_fdlist(fd);
				return;
			} else {
				osafassert(0);	/* This should never occur */
			}
		} else if (2 == node->num_by_read_for_len_buff) {
			int recd_bytes = 0;

			if (NULL == (node->buffer = calloc(1, (node->buff_total_len + 3)))) {
				/* Length + 2 is done to reuse the same buffer 
				   while sending to other nodes */
				LOG_ER("\nMemory allocation failed in dtm_internode_processing");
				return;
			}
			recd_bytes = recv(fd, &node->buffer[2], node->buff_total_len, 0);

			if (recd_bytes < 0) {
				return;
			} else if (0 == recd_bytes) {
				TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
				dtm_intranode_process_pid_down(fd);
				dtm_intranode_del_poll_fdlist(fd);
				return;
			} else if (node->buff_total_len > recd_bytes) {
				/* can happen only in two cases, system call interrupt or half data, */
				TRACE("less data recd, recd bytes = %d, actual len = %d", recd_bytes,
				       node->buff_total_len);
				node->bytes_tb_read = node->buff_total_len - recd_bytes;
				return;
			} else if (node->buff_total_len == recd_bytes) {
				/* Call the common rcv function */
				dtm_intranode_process_poll_rcv_msg_common(node);
			} else {
				osafassert(0);
			}
		} else {
			osafassert(0);
		}

	} else {
		/* Partial data already read */
		int recd_bytes = 0;

		recd_bytes =
		    recv(fd, &node->buffer[2 + (node->buff_total_len - node->bytes_tb_read)], node->bytes_tb_read, 0);

		if (recd_bytes < 0) {
			return;
		} else if (0 == recd_bytes) {
			TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
			/* Close the connection */
			dtm_intranode_process_pid_down(fd);
			dtm_intranode_del_poll_fdlist(fd);
			return;
		} else if (node->bytes_tb_read > recd_bytes) {
			/* can happen only in two cases, system call interrupt or half data, */
			TRACE("less data recd, recd bytes = %d, actual len = %d", recd_bytes, node->bytes_tb_read);
			node->bytes_tb_read = node->bytes_tb_read - recd_bytes;
			return;
		} else if (node->bytes_tb_read == recd_bytes) {
			/* Call the common rcv function */
			dtm_intranode_process_poll_rcv_msg_common(node);
		} else {
			osafassert(0);
		}
	}
	return;
}