1
1
/*
2
- * Copyright (c) 2013 , Peter Thorson. All rights reserved.
2
+ * Copyright (c) 2014 , Peter Thorson. All rights reserved.
3
3
*
4
4
* Redistribution and use in source and binary forms, with or without
5
5
* modification, are permitted provided that the following conditions are met:
@@ -1562,44 +1562,78 @@ void connection<config>::write_frame() {
1562
1562
return ;
1563
1563
}
1564
1564
1565
- // Get the next message in the queue. This will return an empty
1566
- // message if the queue was empty.
1567
- m_current_msg = write_pop ();
1568
-
1569
- if (!m_current_msg) {
1565
+ // pull off all the messages that are ready to write.
1566
+ // stop if we get a message marked terminal
1567
+ message_ptr next_message = write_pop ();
1568
+ while (next_message) {
1569
+ m_current_msgs.push_back (next_message);
1570
+ if (!next_message->get_terminal ()) {
1571
+ next_message = write_pop ();
1572
+ } else {
1573
+ next_message = message_ptr ();
1574
+ }
1575
+ }
1576
+
1577
+ if (m_current_msgs.empty ()) {
1578
+ // there was nothing to send
1570
1579
return ;
1580
+ } else {
1581
+ // At this point we own the next messages to be sent and are
1582
+ // responsible for holding the write flag until they are
1583
+ // successfully sent or there is some error
1584
+ m_write_flag = true ;
1571
1585
}
1572
-
1573
- // At this point we own the next message to be sent and are
1574
- // responsible for holding the write flag until it is successfully
1575
- // sent or there is some error
1576
- m_write_flag = true ;
1577
1586
}
1578
1587
1579
- std::string const & header = m_current_msg->get_header ();
1580
- std::string const & payload = m_current_msg->get_payload ();
1581
-
1582
- m_send_buffer.push_back (transport::buffer (header.c_str (),header.size ()));
1583
- m_send_buffer.push_back (transport::buffer (payload.c_str (),payload.size ()));
1588
+ typename std::vector<message_ptr>::iterator it;
1589
+ for (it = m_current_msgs.begin (); it != m_current_msgs.end (); ++it) {
1590
+ std::string const & header = (*it)->get_header ();
1591
+ std::string const & payload = (*it)->get_payload ();
1584
1592
1593
+ m_send_buffer.push_back (transport::buffer (header.c_str (),header.size ()));
1594
+ m_send_buffer.push_back (transport::buffer (payload.c_str (),payload.size ()));
1595
+ }
1585
1596
1597
+ // Print detailed send stats if those log levels are enabled
1586
1598
if (m_alog.static_test (log ::alevel::frame_header)) {
1587
1599
if (m_alog.dynamic_test (log ::alevel::frame_header)) {
1588
- std::stringstream s;
1589
- s << " Dispatching write with " << header.size ()
1590
- << " header bytes and " << payload.size ()
1591
- << " payload bytes" << std::endl;
1592
- m_alog.write (log ::alevel::frame_header,s.str ());
1593
- m_alog.write (log ::alevel::frame_header," Header: " +utility::to_hex (header));
1594
- }
1595
- }
1596
- if (m_alog.static_test (log ::alevel::frame_payload)) {
1597
- if (m_alog.dynamic_test (log ::alevel::frame_payload)) {
1598
- m_alog.write (log ::alevel::frame_payload," Payload: " +utility::to_hex (payload));
1600
+ std::stringstream general,header,payload;
1601
+
1602
+ general << " Dispatching write containing " << m_current_msgs.size ()
1603
+ <<" message(s) containing " ;
1604
+ header << " Header Bytes: \n " ;
1605
+ payload << " Payload Bytes: \n " ;
1606
+
1607
+ size_t hbytes = 0 ;
1608
+ size_t pbytes = 0 ;
1609
+
1610
+ for (size_t i = 0 ; i < m_current_msgs.size (); i++) {
1611
+ hbytes += m_current_msgs[i]->get_header ().size ();
1612
+ pbytes += m_current_msgs[i]->get_payload ().size ();
1613
+
1614
+
1615
+ header << " [" << i << " ] ("
1616
+ << m_current_msgs[i]->get_header ().size () << " ) "
1617
+ << utility::to_hex (m_current_msgs[i]->get_header ()) << " \n " ;
1618
+
1619
+ if (m_alog.static_test (log ::alevel::frame_payload)) {
1620
+ if (m_alog.dynamic_test (log ::alevel::frame_payload)) {
1621
+ payload << " [" << i << " ] ("
1622
+ << m_current_msgs[i]->get_payload ().size () << " ) "
1623
+ << utility::to_hex (m_current_msgs[i]->get_payload ())
1624
+ << " \n " ;
1625
+ }
1626
+ }
1627
+ }
1628
+
1629
+ general << hbytes << " header bytes and " << pbytes << " payload bytes" ;
1630
+
1631
+ m_alog.write (log ::alevel::frame_header,general.str ());
1632
+ m_alog.write (log ::alevel::frame_header,header.str ());
1633
+ m_alog.write (log ::alevel::frame_payload,payload.str ());
1599
1634
}
1600
1635
}
1601
1636
1602
-
1603
1637
transport_con_type::async_write (
1604
1638
m_send_buffer,
1605
1639
m_write_frame_handler
@@ -1613,10 +1647,11 @@ void connection<config>::handle_write_frame(lib::error_code const & ec)
1613
1647
m_alog.write (log ::alevel::devel," connection handle_write_frame" );
1614
1648
}
1615
1649
1616
- bool terminal = m_current_msg ->get_terminal ();
1650
+ bool terminal = m_current_msgs. back () ->get_terminal ();
1617
1651
1618
1652
m_send_buffer.clear ();
1619
- m_current_msg.reset ();
1653
+ m_current_msgs.clear ();
1654
+ // TODO: recycle instead of deleting
1620
1655
1621
1656
if (ec) {
1622
1657
log_err (log ::elevel::fatal," handle_write_frame" ,ec);
0 commit comments