コード例 #1
0
static int wait_frame_inner(amqp_connection_state_t state,
			    amqp_frame_t *decoded_frame)
{
  while (1) {
    int res;

    while (amqp_data_in_buffer(state)) {
      amqp_bytes_t buffer;
      buffer.len = state->sock_inbound_limit - state->sock_inbound_offset;
      buffer.bytes = ((char *) state->sock_inbound_buffer.bytes) + state->sock_inbound_offset;

      res = amqp_handle_input(state, buffer, decoded_frame);
      if (res < 0)
	return res;

      state->sock_inbound_offset += res;

      if (decoded_frame->frame_type != 0)
	/* Complete frame was read. Return it. */
	return 0;

      /* Incomplete or ignored frame. Keep processing input. */
      assert(res != 0);
    }

    res = recv(state->sockfd, state->sock_inbound_buffer.bytes,
		  state->sock_inbound_buffer.len, 0);
    if (res <= 0) {
      if (res == 0)
	return -ERROR_CONNECTION_CLOSED;
      else
	return -amqp_socket_error();
    }

    state->sock_inbound_limit = res;
    state->sock_inbound_offset = 0;
  }
}
コード例 #2
0
ファイル: amqp_socket.c プロジェクト: neophenix/reconnoiter
static int wait_frame_inner(amqp_connection_state_t state,
                            amqp_frame_t *decoded_frame)
{
    while (1) {
        int result;

        while (amqp_data_in_buffer(state)) {
            amqp_bytes_t buffer;
            buffer.len = state->sock_inbound_limit - state->sock_inbound_offset;
            buffer.bytes = ((char *) state->sock_inbound_buffer.bytes) + state->sock_inbound_offset;
            (void)AMQP_CHECK_RESULT((result = amqp_handle_input(state, buffer, decoded_frame)));
            state->sock_inbound_offset += result;

            if (decoded_frame->frame_type != 0) {
                /* Complete frame was read. Return it. */
                return 1;
            }

            /* Incomplete or ignored frame. Keep processing input. */
            assert(result != 0);
        }

        result = eintr_safe_read(state->sockfd,
                                 state->sock_inbound_buffer.bytes,
                                 state->sock_inbound_buffer.len);
        if (result < 0) {
            mtevL(mtev_error, "Failed to read message in wait_frame_inner, size %zu\n", state->sock_inbound_buffer.len);
            return -errno;
        }
        if (result == 0) {
            /* EOF. */
            return 0;
        }

        state->sock_inbound_limit = result;
        state->sock_inbound_offset = 0;
    }
}
コード例 #3
0
ファイル: lc_bus.c プロジェクト: davidddw/lcm
int lc_bus_data_in_buffer(amqp_connection_state_t *conn)
{
    return amqp_frames_enqueued(*conn) ||
           amqp_data_in_buffer(*conn);
}
コード例 #4
0
bool ChannelImpl::GetNextFrameFromBroker(amqp_frame_t& frame, boost::chrono::microseconds timeout)
{
    int socketno = amqp_get_sockfd(m_connection);

start:
    // Possibly set a timeout on receiving
    if (timeout != boost::chrono::microseconds::max() && !amqp_frames_enqueued(m_connection) && !amqp_data_in_buffer(m_connection))
    {
        struct timeval tv_timeout;
        memset(&tv_timeout, 0, sizeof(tv_timeout));

        // boost::chrono::seconds.count() returns boost::int_atleast64_t,
        // long can be 32 or 64 bit depending on the platform/arch
        // unless the timeout is something absurd cast to long will be ok, but
        // lets guard against the case where someone does something silly
        assert(boost::chrono::duration_cast<boost::chrono::seconds>(timeout).count() <
               static_cast<boost::chrono::seconds::rep>(std::numeric_limits<long>::max()));

        tv_timeout.tv_sec = static_cast<long>(boost::chrono::duration_cast<boost::chrono::seconds>(timeout).count());
        tv_timeout.tv_usec = static_cast<long>((timeout - boost::chrono::seconds(tv_timeout.tv_sec)).count());

        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(static_cast<unsigned int>(socketno), &fds);

        int select_return = select(socketno + 1, &fds, NULL, &fds, &tv_timeout);

        if (select_return == 0) // If it times out, return
        {
            return false;
        }
        else if (select_return == -1)
        {
            // If its an interupted system call just try again
            if (errno == EINTR)
            {
                goto start;
            }
            else
            {
                std::string error_string("error calling select on socket: ");
#ifdef HAVE_STRERROR_S
                const int BUFFER_LENGTH = 256;
                char error_string_buffer[BUFFER_LENGTH] = {0};
                strerror_s(error_string_buffer, errno);
                error_string += error_string_buffer;
#elif defined(HAVE_STRERROR_R)
                const int BUFFER_LENGTH = 256;
                char error_string_buffer[BUFFER_LENGTH] = {0};
                strerror_r(errno, error_string_buffer, BUFFER_LENGTH);
                error_string += error_string_buffer;
#else
                error_string += strerror(errno);
#endif
                throw std::runtime_error(error_string.c_str());
            }
        }
    }

    CheckForError(amqp_simple_wait_frame(m_connection, &frame));
    return true;
}