Пример #1
0
bq_thr_t::impl_t::impl_t(
	size_t _maxevs, interval_t _timeout, bq_cont_count_t &_cont_count,
	bq_post_activate_t *_post_activate
) :
	cont_count(_cont_count), post_activate(_post_activate),
	thread(0), tid(0),
	maxevs(_maxevs), timeout(_timeout), stat(), entry() {

	efd = epoll_create(maxevs);
	if(efd < 0)
		throw exception_sys_t(log::error, errno, "bq_thr_t::impl_t::impl_t, epoll_create: %m");

	if(::pipe(sig_fds) < 0)
		throw exception_sys_t(log::error, errno, "bq_thr_t::impl_t::impl_t, pipe: %m");

	bq_fd_setup(sig_fds[0]);
	bq_fd_setup(sig_fds[1]);

	epoll_event ev;
	ev.events = POLLIN;
	ev.data.ptr = NULL;

	if(epoll_ctl(efd, EPOLL_CTL_ADD, sig_fds[0], &ev) < 0)
		throw exception_sys_t(log::error, errno, "bq_thr_t::impl_t::impl_t, epoll_ctl, add: %m");
}
Пример #2
0
void io_stream_t::init() {
	netaddr_t const &netaddr = bind_addr();

	fd = socket(netaddr.sa->sa_family, SOCK_STREAM, 0);
	if(fd < 0)
		throw exception_sys_t(log::error, errno, "socket: %m");

	try {
		bq_fd_setup(fd);
		fd_setup(fd);

		if(reuse_addr) {
			int i = 1;
			if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
				throw exception_sys_t(log::error, errno, "setsockopt, SO_REUSEADDR, 1: %m");
		}

		if(::bind(fd, netaddr.sa, netaddr.sa_len) < 0)
			throw exception_sys_t(log::error, errno, "bind: %m");

		if(::listen(fd, listen_backlog) < 0)
			throw exception_sys_t(log::error, errno, "listen: %m");

	}
	catch(...) {
		::close(fd);
		fd = -1;
		throw;
	}

	stat.init();
	proto.init(name);
}
Пример #3
0
void link_t::loop() {
	timeval_t last_conn = timeval_long_ago;

	while(true) {
		try {
			{
				timeval_t now = timeval_current();
				interval_t to_sleep = conn_timeout - (timeval_current() - last_conn);

				if(to_sleep > interval_zero && bq_sleep(&to_sleep) < 0)
					throw exception_sys_t(log::error, errno, "bq_sleep: %m");

			}

			last_conn = timeval_current();

			netaddr_t const &netaddr = remote_netaddr();

			int fd = socket(netaddr.sa->sa_family, SOCK_STREAM, 0);
			if(fd < 0)
				throw exception_sys_t(remote_errors, errno, "socket: %m");

			fd_guard_t fd_guard(fd);

			bq_fd_setup(fd);

			interval_t timeout = conn_timeout;

			if(bq_connect(fd, netaddr.sa, netaddr.sa_len, &timeout) < 0)
				throw exception_sys_t(remote_errors, errno, "connect: %m");

			log_debug("connected");

			bq_conn_fd_t conn(fd, ctl(), remote_errors, /* dup = */ true);

			proto_instance->proc(conn);
		}
		catch(exception_sys_t const &ex) {
			if(ex.errno_val == ECANCELED)
				throw;

			ex.log();
		}
		catch(exception_t const &ex) {
			ex.log();
		}
	}
}
Пример #4
0
int method_datagram_t::connect_fd() {
    const netaddr_t& addr = target_addr();

    int fd = socket(addr.sa->sa_family, SOCK_DGRAM, 0);
    if(fd < 0) {
        throw exception_sys_t(log::error, errno, "socket: %m");
    }

    bq_fd_setup(fd);

    if(bq_connect(fd, addr.sa, addr.sa_len, NULL) < 0) {
        throw exception_sys_t(log::error, errno, "connect: %m");
    }

    return fd;
}
Пример #5
0
void io_stream_t::conn_proc(int fd, netaddr_t *netaddr) const {
	fd_guard_t fd_guard(fd);

	class netaddr_guard_t {
		netaddr_t *netaddr;
	public:
		inline netaddr_guard_t(netaddr_t *_netaddr) throw() : netaddr(_netaddr) { }
		inline ~netaddr_guard_t() throw() { delete netaddr; }
	} netaddr_guard(netaddr);

	bq_fd_setup(fd);

	bq_conn_t *conn = transport.new_connect(fd, ctl(), remote_errors);

	class conn_guard_t {
		bq_conn_t *conn;
		io_stream::mmconns_t &mmconns;
	public:
		inline conn_guard_t(bq_conn_t *_conn, stat_t &stat) throw() :
			conn(_conn), mmconns(stat.mmconns()) {

			++mmconns;
		}

		inline ~conn_guard_t() throw() {
			--mmconns;

			delete conn;
		}
	} conn_guard(conn, stat);

	conn->setup_accept();

	netaddr_t const &local_addr = bind_addr();

	bq_in_t in(*conn, ibuf_size, &stat.icount());

	for(bool work = true; work;) {
		{
			char obuf[obuf_size];
			bq_out_t out(*conn, obuf, sizeof(obuf), &stat.ocount());

			in_t::ptr_t ptr(in);

			do {
				in.timeout_set(timeout);
				out.timeout_set(timeout);

				work = proto.request_proc(ptr, out, local_addr, *netaddr);
				++stat.reqs();

				if(!work)
					break;

			} while(in.truncate(ptr));
		}

		if(work) {
			short int events = POLLIN;
			interval_t _keepalive = keepalive;
			if(bq_poll(fd, events, &_keepalive) < 0)
				break;
		}
	}

	conn->shutdown();
}