void messaging_adapter::on_session_remote_open(proton_event &pe) { pn_session_t *session = pn_event_session(pe.pn_event()); class session s(make_wrapper(session)); delegate_.on_session_open(s); if (!is_local_open(pn_session_state(session)) && is_local_unititialised(pn_session_state(session))) { pn_session_open(session); } }
static void pn_handshaker_dispatch(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type) { switch (type) { case PN_CONNECTION_REMOTE_OPEN: { pn_connection_t *conn = pn_event_connection(event); if (pn_connection_state(conn) & PN_LOCAL_UNINIT) { pn_connection_open(conn); } } break; case PN_SESSION_REMOTE_OPEN: { pn_session_t *ssn = pn_event_session(event); if (pn_session_state(ssn) & PN_LOCAL_UNINIT) { pn_session_open(ssn); } } break; case PN_LINK_REMOTE_OPEN: { pn_link_t *link = pn_event_link(event); if (pn_link_state(link) & PN_LOCAL_UNINIT) { pn_terminus_copy(pn_link_source(link), pn_link_remote_source(link)); pn_terminus_copy(pn_link_target(link), pn_link_remote_target(link)); pn_link_open(link); } } break; case PN_CONNECTION_REMOTE_CLOSE: { pn_connection_t *conn = pn_event_connection(event); if (!(pn_connection_state(conn) & PN_LOCAL_CLOSED)) { pn_connection_close(conn); } } break; case PN_SESSION_REMOTE_CLOSE: { pn_session_t *ssn = pn_event_session(event); if (!(pn_session_state(ssn) & PN_LOCAL_CLOSED)) { pn_session_close(ssn); } } break; case PN_LINK_REMOTE_CLOSE: { pn_link_t *link = pn_event_link(event); if (!(pn_link_state(link) & PN_LOCAL_CLOSED)) { pn_link_close(link); } } break; default: break; } }
void messaging_adapter::on_session_remote_open(event &e) { proton_event *pe = dynamic_cast<proton_event*>(&e); if (pe) { messaging_event mevent(messaging_event::SESSION_OPEN, *pe); on_session_open(mevent); pn_session_t *session = pn_event_session(pe->pn_event()); if (!is_local_open(pn_session_state(session)) && is_local_unititialised(pn_session_state(session))) { pn_session_open(session); } } }
void ConnectionContext::close() { qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock); if (state != CONNECTED) return; if (!(pn_connection_state(connection) & PN_LOCAL_CLOSED)) { for (SessionMap::iterator i = sessions.begin(); i != sessions.end(); ++i) { //wait for outstanding sends to settle while (!i->second->settled()) { QPID_LOG(debug, "Waiting for sends to settle before closing"); wait();//wait until message has been confirmed } if (!(pn_session_state(i->second->session) & PN_LOCAL_CLOSED)) { pn_session_close(i->second->session); } } pn_connection_close(connection); wakeupDriver(); //wait for close to be confirmed by peer? while (!(pn_connection_state(connection) & PN_REMOTE_CLOSED)) { wait(); } sessions.clear(); } transport->close(); while (state != DISCONNECTED) { lock.wait(); } }
boost::shared_ptr<SessionContext> ConnectionContext::newSession(bool transactional, const std::string& n) { qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock); if (transactional) throw qpid::messaging::MessagingException("Transactions not yet supported"); std::string name = n.empty() ? qpid::framing::Uuid(true).str() : n; SessionMap::const_iterator i = sessions.find(name); if (i == sessions.end()) { boost::shared_ptr<SessionContext> s(new SessionContext(connection)); s->session = pn_session(connection); pn_session_open(s->session); sessions[name] = s; wakeupDriver(); while (pn_session_state(s->session) & PN_REMOTE_UNINIT) { wait(); } return s; } else { throw qpid::messaging::KeyError(std::string("Session already exists: ") + name); } }
void messaging_adapter::on_session_remote_close(event &e) { proton_event *pe = dynamic_cast<proton_event*>(&e); if (pe) { pn_event_t *cevent = pe->pn_event(); pn_session_t *session = pn_event_session(cevent); pn_state_t state = pn_session_state(session); if (pn_condition_is_set(pn_session_remote_condition(session))) { messaging_event mevent(messaging_event::SESSION_ERROR, *pe); on_session_error(mevent); } else if (is_local_closed(state)) { messaging_event mevent(messaging_event::SESSION_CLOSED, *pe); on_session_closed(mevent); } else { messaging_event mevent(messaging_event::SESSION_CLOSING, *pe); on_session_closing(mevent); } pn_session_close(session); } }
endpoint::state session::state() const { return pn_session_state(pn_object()); }
int pn_event_handler(void *handler_context, void *conn_context, pn_event_t *event, qd_connection_t *qd_conn) { qd_container_t *container = (qd_container_t*) handler_context; pn_connection_t *conn = qd_connection_pn(qd_conn); pn_session_t *ssn; pn_link_t *pn_link; qd_link_t *qd_link; pn_delivery_t *delivery; switch (pn_event_type(event)) { case PN_CONNECTION_REMOTE_OPEN : qd_connection_set_user(qd_conn); if (pn_connection_state(conn) & PN_LOCAL_UNINIT) { // This Open is an externally initiated connection // Let policy engine decide qd_connection_set_event_stall(qd_conn, true); qd_conn->open_container = (void *)container; qd_connection_invoke_deferred(qd_conn, qd_policy_amqp_open, qd_conn); } else { // This Open is in response to an internally initiated connection notify_opened(container, qd_conn, conn_context); } break; case PN_CONNECTION_REMOTE_CLOSE : if (pn_connection_state(conn) == (PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED)) pn_connection_close(conn); break; case PN_SESSION_REMOTE_OPEN : if (!(pn_connection_state(conn) & PN_LOCAL_CLOSED)) { ssn = pn_event_session(event); if (pn_session_state(ssn) & PN_LOCAL_UNINIT) { if (qd_conn->policy_settings) { if (!qd_policy_approve_amqp_session(ssn, qd_conn)) { break; } qd_conn->n_sessions++; } qd_policy_apply_session_settings(ssn, qd_conn); pn_session_open(ssn); } } break; case PN_SESSION_REMOTE_CLOSE : if (!(pn_connection_state(conn) & PN_LOCAL_CLOSED)) { ssn = pn_event_session(event); if (pn_session_state(ssn) == (PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED)) { // remote has nuked our session. Check for any links that were // left open and forcibly detach them, since no detaches will // arrive on this session. pn_connection_t *conn = pn_session_connection(ssn); pn_link_t *pn_link = pn_link_head(conn, PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE); while (pn_link) { if (pn_link_session(pn_link) == ssn) { qd_link_t *qd_link = (qd_link_t*) pn_link_get_context(pn_link); if (qd_link && qd_link->node) { if (qd_conn->policy_settings) { if (qd_link->direction == QD_OUTGOING) { qd_conn->n_receivers--; assert(qd_conn->n_receivers >= 0); } else { qd_conn->n_senders--; assert(qd_conn->n_senders >= 0); } } qd_log(container->log_source, QD_LOG_NOTICE, "Aborting link '%s' due to parent session end", pn_link_name(pn_link)); qd_link->node->ntype->link_detach_handler(qd_link->node->context, qd_link, QD_LOST); } } pn_link = pn_link_next(pn_link, PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE); } if (qd_conn->policy_settings) { qd_conn->n_sessions--; } pn_session_close(ssn); } } break; case PN_LINK_REMOTE_OPEN : if (!(pn_connection_state(conn) & PN_LOCAL_CLOSED)) { pn_link = pn_event_link(event); if (pn_link_state(pn_link) & PN_LOCAL_UNINIT) { if (pn_link_is_sender(pn_link)) { if (qd_conn->policy_settings) { if (!qd_policy_approve_amqp_receiver_link(pn_link, qd_conn)) { break; } qd_conn->n_receivers++; } setup_outgoing_link(container, pn_link); } else { if (qd_conn->policy_settings) { if (!qd_policy_approve_amqp_sender_link(pn_link, qd_conn)) { break; } qd_conn->n_senders++; } setup_incoming_link(container, pn_link); } } else if (pn_link_state(pn_link) & PN_LOCAL_ACTIVE) handle_link_open(container, pn_link); } break; case PN_LINK_REMOTE_CLOSE : case PN_LINK_REMOTE_DETACH : if (!(pn_connection_state(conn) & PN_LOCAL_CLOSED)) { pn_link = pn_event_link(event); qd_link = (qd_link_t*) pn_link_get_context(pn_link); if (qd_link) { qd_node_t *node = qd_link->node; qd_detach_type_t dt = pn_event_type(event) == PN_LINK_REMOTE_CLOSE ? QD_CLOSED : QD_DETACHED; if (node) node->ntype->link_detach_handler(node->context, qd_link, dt); else if (qd_link->pn_link == pn_link) { pn_link_close(pn_link); } if (qd_conn->policy_counted && qd_conn->policy_settings) { if (pn_link_is_sender(pn_link)) { qd_conn->n_receivers--; qd_log(container->log_source, QD_LOG_TRACE, "Closed receiver link %s. n_receivers: %d", pn_link_name(pn_link), qd_conn->n_receivers); assert (qd_conn->n_receivers >= 0); } else { qd_conn->n_senders--; qd_log(container->log_source, QD_LOG_TRACE, "Closed sender link %s. n_senders: %d", pn_link_name(pn_link), qd_conn->n_senders); assert (qd_conn->n_senders >= 0); } } if (qd_link->close_sess_with_link && qd_link->pn_sess && pn_link_state(pn_link) == (PN_LOCAL_CLOSED | PN_REMOTE_CLOSED)) pn_session_close(qd_link->pn_sess); } } break; case PN_LINK_FLOW : pn_link = pn_event_link(event); qd_link = (qd_link_t*) pn_link_get_context(pn_link); if (qd_link && qd_link->node && qd_link->node->ntype->link_flow_handler) qd_link->node->ntype->link_flow_handler(qd_link->node->context, qd_link); break; case PN_DELIVERY : delivery = pn_event_delivery(event); if (pn_delivery_readable(delivery)) do_receive(delivery); if (pn_delivery_updated(delivery)) { do_updated(delivery); pn_delivery_clear(delivery); } break; case PN_EVENT_NONE : case PN_REACTOR_INIT : case PN_REACTOR_QUIESCED : case PN_REACTOR_FINAL : case PN_TIMER_TASK : case PN_CONNECTION_INIT : case PN_CONNECTION_BOUND : case PN_CONNECTION_UNBOUND : case PN_CONNECTION_LOCAL_OPEN : case PN_CONNECTION_LOCAL_CLOSE : case PN_CONNECTION_FINAL : case PN_SESSION_INIT : case PN_SESSION_LOCAL_OPEN : case PN_SESSION_LOCAL_CLOSE : case PN_SESSION_FINAL : case PN_LINK_INIT : case PN_LINK_LOCAL_OPEN : case PN_LINK_LOCAL_CLOSE : case PN_LINK_LOCAL_DETACH : case PN_LINK_FINAL : case PN_TRANSPORT : case PN_TRANSPORT_ERROR : case PN_TRANSPORT_HEAD_CLOSED : case PN_TRANSPORT_TAIL_CLOSED : case PN_TRANSPORT_CLOSED : case PN_TRANSPORT_AUTHENTICATED : case PN_SELECTABLE_INIT : case PN_SELECTABLE_UPDATED : case PN_SELECTABLE_READABLE : case PN_SELECTABLE_WRITABLE : case PN_SELECTABLE_ERROR : case PN_SELECTABLE_EXPIRED : case PN_SELECTABLE_FINAL : break; } return 1; }
bool session::closed() const { return ::closed(pn_session_state(pn_object())); }
bool session::active() const { return ::active(pn_session_state(pn_object())); }
bool session::uninitialized() const { return ::uninitialized(pn_session_state(pn_object())); }