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"); }
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); }
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(); } } }
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; }
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(); }