This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/main by this push:
     new f873b3c  PROTON-2375: Small connection_driver API change
f873b3c is described below

commit f873b3cd7d20b3ae6c0510ec7d0f8a0c2f6bbcfd
Author: Andrew Stitcher <astitc...@apache.org>
AuthorDate: Tue Mar 16 16:09:31 2021 -0400

    PROTON-2375: Small connection_driver API change
    
    Make connection_driver API more efficient when finishing writes
    
    This allows epoll proactor to efficiently avoid delving directly into
    the transport buffers.
    
    Also small small clean ups.
---
 c/include/proton/connection_driver.h        |  2 +-
 c/src/core/connection_driver.c              |  5 ++++-
 c/src/core/transport.c                      | 11 +++++------
 c/src/proactor/epoll.c                      | 10 +++-------
 cpp/include/proton/io/connection_driver.hpp |  2 +-
 cpp/src/connection_driver.cpp               |  5 +++--
 6 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/c/include/proton/connection_driver.h 
b/c/include/proton/connection_driver.h
index aa703b5..b172643 100644
--- a/c/include/proton/connection_driver.h
+++ b/c/include/proton/connection_driver.h
@@ -177,7 +177,7 @@ PN_EXTERN bool 
pn_connection_driver_read_closed(pn_connection_driver_t *);
  * Call when the first n bytes of pn_connection_driver_write_buffer() have been
  * written to IO. Reclaims the buffer space and reset the write buffer.
  */
-PN_EXTERN void pn_connection_driver_write_done(pn_connection_driver_t *, 
size_t n);
+PN_EXTERN pn_bytes_t pn_connection_driver_write_done(pn_connection_driver_t *, 
size_t n);
 
 /**
  * Close the write side. Call when IO can no longer be written to.
diff --git a/c/src/core/connection_driver.c b/c/src/core/connection_driver.c
index 5947338..1305a12 100644
--- a/c/src/core/connection_driver.c
+++ b/c/src/core/connection_driver.c
@@ -114,8 +114,11 @@ pn_bytes_t 
pn_connection_driver_write_buffer(pn_connection_driver_t *d) {
     pn_bytes(pending, pn_transport_head(d->transport)) : pn_bytes_null;
 }
 
-void pn_connection_driver_write_done(pn_connection_driver_t *d, size_t n) {
+pn_bytes_t pn_connection_driver_write_done(pn_connection_driver_t *d, size_t 
n) {
   pn_transport_pop(d->transport, n);
+  ssize_t pending = d->transport->output_pending;
+  return (pending > 0) ?
+    pn_bytes(pending, pn_transport_head(d->transport)) : pn_bytes_null;
 }
 
 bool pn_connection_driver_write_closed(pn_connection_driver_t *d) {
diff --git a/c/src/core/transport.c b/c/src/core/transport.c
index 0467eef..98270fd 100644
--- a/c/src/core/transport.c
+++ b/c/src/core/transport.c
@@ -3145,14 +3145,13 @@ void pn_transport_pop(pn_transport_t *transport, size_t 
size)
     transport->output_pending -= size;
     transport->bytes_output += size;
     if (transport->output_pending) {
+      // TODO: This could be potentially inefficient if we often pop the 
output without emptying it
+      // TODO: as we rotate the buffer here if we have any bytes left to write.
       memmove( transport->output_buf,  &transport->output_buf[size],
                transport->output_pending );
-    }
-
-    if (transport->output_pending==0 && pn_transport_pending(transport) < 0) {
-      // TODO: It looks to me that this is a NOP as iff we ever get here
-      // TODO: pni_close_head() will always have been already called before 
leaving pn_transport_pending()
-      pni_close_head(transport);
+    } else {
+      // If we emptied the output buffer then see if there's more output 
pending
+      pn_transport_pending(transport);
     }
   }
 }
diff --git a/c/src/proactor/epoll.c b/c/src/proactor/epoll.c
index 876c55a..52e05c1 100644
--- a/c/src/proactor/epoll.c
+++ b/c/src/proactor/epoll.c
@@ -1050,11 +1050,9 @@ static bool pconnection_write(pconnection_t *pc) {
     }
     else {
       // write_done also calls pn_transport_pending(), so the transport knows 
all current output
-      pn_connection_driver_write_done(&pc->driver, pc->wbuf_completed);
-      pc->wbuf_completed = 0;
-      pn_transport_t *t = pc->driver.transport;
-      set_wbuf(pc, t->output_buf, t->output_pending);
-      if (t->output_pending == 0)
+      pn_bytes_t bytes = pn_connection_driver_write_done(&pc->driver, 
pc->wbuf_completed);
+      set_wbuf(pc, bytes.start, bytes.size);
+      if (bytes.size == 0)
         pc->output_drained = true;
       // TODO: revise transport API to allow similar efficient access to 
transport output
     }
@@ -1074,8 +1072,6 @@ static void write_flush(pconnection_t *pc) {
   while(!pc->write_blocked && !pc->output_drained && !pconnection_wclosed(pc)) 
{
     if (pc->wbuf_remaining == 0) {
       ensure_wbuf(pc);
-      if (pc->wbuf_remaining == 0)
-        pc->output_drained = true;
     } else {
       // Check if we are doing multiple small writes in a row, possibly worth 
growing the transport output buffer.
       if (prev_wbuf_remaining
diff --git a/cpp/include/proton/io/connection_driver.hpp 
b/cpp/include/proton/io/connection_driver.hpp
index 33026e0..390a5c4 100644
--- a/cpp/include/proton/io/connection_driver.hpp
+++ b/cpp/include/proton/io/connection_driver.hpp
@@ -138,7 +138,7 @@ PN_CPP_CLASS_EXTERN connection_driver {
 
     /// Indicate that the first n bytes of write_buffer() have been written 
successfully.
     /// This changes the buffer, call write_buffer() to get the updated buffer.
-    PN_CPP_EXTERN void write_done(size_t n);
+    PN_CPP_EXTERN const_buffer write_done(size_t n);
 
     /// Indicate that the write side of the transport has closed and no more 
data can be written.
     /// Note that there may still be events to dispatch() or data to read.
diff --git a/cpp/src/connection_driver.cpp b/cpp/src/connection_driver.cpp
index 11888be..038fe4e 100644
--- a/cpp/src/connection_driver.cpp
+++ b/cpp/src/connection_driver.cpp
@@ -126,8 +126,9 @@ const_buffer connection_driver::write_buffer() {
     return const_buffer(buffer.start, buffer.size);
 }
 
-void connection_driver::write_done(size_t n) {
-    return pn_connection_driver_write_done(&driver_, n);
+const_buffer connection_driver::write_done(size_t n) {
+    pn_bytes_t buffer = pn_connection_driver_write_done(&driver_, n);
+    return const_buffer(buffer.start, buffer.size);
 }
 
 void connection_driver::write_close() {

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to