int php_amqp_set_resource_write_timeout(amqp_connection_resource *resource, double timeout TSRMLS_DC)
{
	assert(timeout >= 0.0);

#ifdef PHP_WIN32
	DWORD write_timeout;

	if (timeout == 0.) {
		write_timeout = 0;
	} else {
		write_timeout = (int) (max(timeout * 1.e+3 - .5e+3, 1.));
	}
#else
	struct timeval write_timeout;
	write_timeout.tv_sec = (int) floor(timeout);
	write_timeout.tv_usec = (int) ((timeout - floor(timeout)) * 1.e+6);
#endif

	if (0 != setsockopt(amqp_get_sockfd(resource->connection_state), SOL_SOCKET, SO_SNDTIMEO, (char *)&write_timeout, sizeof(write_timeout))) {
		zend_throw_exception(amqp_connection_exception_class_entry, "Socket error: cannot setsockopt SO_SNDTIMEO", 0 TSRMLS_CC);
		return 0;
	}

	return 1;
}
/* Socket-related functions */
int php_amqp_set_resource_read_timeout(amqp_connection_resource *resource, double timeout TSRMLS_DC)
{
	assert(timeout >= 0.0);

#ifdef PHP_WIN32
	DWORD read_timeout;
	/*
	In Windows, setsockopt with SO_RCVTIMEO sets actual timeout
	to a value that's 500ms greater than specified value.
	Also, it's not possible to set timeout to any value below 500ms.
	Zero timeout works like it should, however.
	*/
	if (timeout == 0.) {
		read_timeout = 0;
	} else {
		read_timeout = (int) (max(connection->read_timeout * 1.e+3 - .5e+3, 1.));
	}
#else
	struct timeval read_timeout;
	read_timeout.tv_sec = (int) floor(timeout);
	read_timeout.tv_usec = (int) ((timeout - floor(timeout)) * 1.e+6);
#endif

	if (0 != setsockopt(amqp_get_sockfd(resource->connection_state), SOL_SOCKET, SO_RCVTIMEO, (char *)&read_timeout, sizeof(read_timeout))) {
		zend_throw_exception(amqp_connection_exception_class_entry, "Socket error: cannot setsockopt SO_RCVTIMEO", 0 TSRMLS_CC);
		return 0;
	}

	return 1;
}
Example #3
0
/*
 * Functions
 */
static void camqp_close_connection (camqp_config_t *conf) /* {{{ */
{
    int sockfd;

    if ((conf == NULL) || (conf->connection == NULL))
        return;

    sockfd = amqp_get_sockfd (conf->connection);
    amqp_channel_close (conf->connection, CAMQP_CHANNEL, AMQP_REPLY_SUCCESS);
    amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS);
    amqp_destroy_connection (conf->connection);
    close (sockfd);
    conf->connection = NULL;
} /* }}} void camqp_close_connection */
Example #4
0
int recv_message(uint8_t **body, size_t *len)
{
    int head_len = get_message_header_pb_len();
    amqp_connection_state_t *conn = lc_bus_get_connection();
    int fd = amqp_get_sockfd(*conn);
    int max_fd = fd + 1;
    fd_set fds;
    amqp_envelope_t envelope;
    amqp_frame_t frame;
    amqp_message_t message;
    char buf[RECV_BUFSIZE] = {0};
    int buf_len;
    Header__Header *p_head = 0;

    FD_ZERO(&fds);
    FD_SET(fd, &fds);
    if (select(max_fd, &fds, 0, 0, 0) > 0) {
        buf_len = lc_bus_consume_message(conn, 0, &envelope, &frame, &message,
                                         buf, sizeof(buf));
    } else {
        return -1;
    }
    if (buf_len < head_len) {
        return -1;
    }
    p_head = header__header__unpack(0, head_len, (uint8_t *)buf);
    if (!p_head || head_len + p_head->length != buf_len) {
        return -1;
    }
    *body = calloc(1, p_head->length);
    if (!*body) {
        return -1;
    }
    memcpy(*body, buf + head_len, p_head->length);
    *len = p_head->length;
    header__header__free_unpacked(p_head, 0);

    return 0;
}
Example #5
0
static
amqp_connection_state_t setup_amqp_connection()
{
    amqp_connection_state_t connection = amqp_new_connection();
    amqp_socket_t *socket = amqp_tcp_socket_new(connection);

#ifdef FIX_SIG_PIPE
    // why doesn't librabbitmq do this, eh?
    int sockfd = amqp_get_sockfd(connection);
    int one = 1; //
    setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one));
#endif

    int status = amqp_socket_open(socket, rabbit_host, rabbit_port);
    assert_x(!status, "Opening RabbitMQ socket", __FILE__, __LINE__);

    die_on_amqp_error(amqp_login(connection, "/", 0, OUR_FRAME_MAX, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
                      "Logging in to RabbitMQ");
    amqp_channel_open(connection, 1);
    die_on_amqp_error(amqp_get_rpc_reply(connection), "Opening AMQP channel");

    return connection;
}
Example #6
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;
}
Example #7
0
int Channel::GetSocketFD() const {
  return amqp_get_sockfd(m_impl->m_connection);
}