[Ace-users] nonblock io

joe joelihn at hotmail.com
Fri Oct 19 01:36:48 CDT 2007


Subject: nonblock io
ACE VERSION: 5.5.10
HOST MACHINE and OPERATING SYSTEM:    winxp
COMPILER NAME AND VERSION (AND PATCHLEVEL): g++
THE $ACE_ROOT/ace/config.h FILE : #include "ace/config-win32.h"
THE $ACE_ROOT/include/makeinclude/platform_macros.GNU
FILE :platform_macros.GNU
DESCRIPTION: The recv fuction like ACE_wrappers\apps\Gateway\Peer
\Peer.cpp recv function.When i didn't get the whole event or i've got
an entire event everytime, do i need sleep a short time?

............
if (this->msg_frag_ == 0) {
		// No existing fragment... loog out delete last new mem
		ACE_NEW_RETURN (this->msg_frag_,
				ACE_Message_Block (MAX_PACKET_LEN),
				-1);
	}

	MRI_NET_HEADER *mnh = (MRI_NET_HEADER *) this->msg_frag_->rd_ptr();
	ssize_t header_received = 0;

	const size_t HEADER_SIZE = sizeof(MRI_NET_HEADER);
	ssize_t header_bytes_left_to_read =HEADER_SIZE - this->msg_frag_-
>length();

	if (header_bytes_left_to_read > 0) {
		header_received = ::g_host_stream_sock().recv(this->msg_frag_-
>wr_ptr(), header_bytes_left_to_read);

		if (header_received == -1 /* error */
		|| header_received == 0 /* EOF */) {
			ACE_ERROR ((LM_ERROR,
							ACE_TEXT ("%p\n"),
							ACE_TEXT ("Recv error during header read")));
			ACE_DEBUG ((LM_DEBUG,
							ACE_TEXT ("attempted to read %d bytes\n"),
							header_bytes_left_to_read));
			this->msg_frag_ = this->msg_frag_->release();
			return header_received;
		}

		// Bump the write pointer by the amount read.
		this->msg_frag_->wr_ptr(header_received);

		// At this point we may or may not have the ENTIRE header.
		if (this->msg_frag_->length() < HEADER_SIZE) {
			ACE_DEBUG ((LM_DEBUG,
							ACE_TEXT ("Partial header received: only %d bytes\n"),
							this->msg_frag_->length ()));
			// Notify the caller that we didn't get an entire mnh.
			errno = EWOULDBLOCK;
			return -1;
		}

	}

	//Here We get a whole message header already.
	//Now we need to get the event payload.
	ssize_t data_bytes_left_to_read = ssize_t (mnh->wLen - msg_frag_-
>length());

	while (data_bytes_left_to_read >=0) {
		ssize_t data_received = !data_bytes_left_to_read ? 0
				: ::g_host_stream_sock().recv(this->msg_frag_->wr_ptr(),
						data_bytes_left_to_read);

		// Try to receive the remainder of the message.
		switch (data_received) {
		case -1:
			if (errno == EWOULDBLOCK) {
				// This might happen if only the header came through.
				return -1;
			} else
				/* FALLTHROUGH */;

		case 0: // Premature EOF.
			if (data_bytes_left_to_read) {
				this->msg_frag_ = this->msg_frag_->release();
				return 0;
			}
			/* FALLTHROUGH */
			;

		default:
			// Set the write pointer at 1 past the end of the event.
			this->msg_frag_->wr_ptr(data_received);

			ACE_Time_Value interval = ACE_Time_Value (0, 1000);
			if (data_received != data_bytes_left_to_read) {
				ACE_OS::sleep(interval);
				ssize_t tmp = data_bytes_left_to_read;
				data_bytes_left_to_read = tmp - data_received;
				break;
			} else {
				ACE_OS::sleep(interval);
				// Set the read pointer to the beginning of the event.
				this->msg_frag_->rd_ptr(this->msg_frag_->base());

				mb = this->msg_frag_;

				// Reset the pointer to indicate we've got an entire event.
				this->msg_frag_ = 0;
			}

			return 1;
		}//switch
	}//while
...........



More information about the Ace-users mailing list