static void pni_connection_readable(pn_selectable_t *sel) { pn_reactor_t *reactor = (pn_reactor_t *) pni_selectable_get_context(sel); pn_transport_t *transport = pni_transport(sel); ssize_t capacity = pn_transport_capacity(transport); if (capacity > 0) { ssize_t n = pn_recv(pni_reactor_io(reactor), pn_selectable_get_fd(sel), pn_transport_tail(transport), capacity); if (n <= 0) { if (n == 0 || !pn_wouldblock(pni_reactor_io(reactor))) { if (n < 0) { pn_condition_t *cond = pn_transport_condition(transport); pn_condition_set_name(cond, "proton:io"); pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor))); } pn_transport_close_tail(transport); } } else { pn_transport_process(transport, (size_t)n); } } ssize_t newcap = pn_transport_capacity(transport); //occasionally transport events aren't generated when expected, so //the following hack ensures we always update the selector if (1 || newcap != capacity) { pni_connection_update(sel); pn_reactor_update(reactor, sel); } }
mutable_buffer connection_engine::read_buffer() { ssize_t cap = pn_transport_capacity(unwrap(transport_)); if (cap > 0) return mutable_buffer(pn_transport_tail(unwrap(transport_)), cap); else return mutable_buffer(0, 0); }
void connection_engine::try_read() { size_t max = can_read(); if (max == 0) return; try { size_t n = io_read(pn_transport_tail(ctx_->transport), max); if (n > max) throw io_error(msg() << "read invalid size: " << n << " > " << max); pn_transport_process(ctx_->transport, n); } catch (const closed_error&) { pn_transport_close_tail(ctx_->transport); } catch (const io_error& e) { set_error(ctx_, e.what()); pn_transport_close_tail(ctx_->transport); } }