Author: rhuijben
Date: Sun Oct 18 11:51:53 2015
New Revision: 1709265

URL: http://svn.apache.org/viewvc?rev=1709265&view=rev
Log:
Abstract the read, write and hangup events in the connection processing code
a bit by using a callback registered on the connection to call the actual
functions.

This introduces a bit of plumbing to allow developing a new protocol without
having to plug in the existing http1 request pipeline.

The patch initializes the callback and resets the callbacks on connection
close, but doesn't change the callbacks yet.

* serf-dev/dev/outgoing.c
  (read_from_connection,
   write_to_connection,
   hangup_connection): Forward definitions.
  (reset_connection): Reset functions on reset.
  (hangup_connection): New function, directly extracted from
    serf__process_connection.

  (serf__process_connection): Call read_from_connection, write_to_connection
    and hangup_connection via callbacks on the connection instead of directly.
  (serf_connection_create): Initialize callbacks.

* serf-dev/dev/serf_private.h
  (serf_connection_t): Add 3 callbacks.

Modified:
    serf/trunk/outgoing.c
    serf/trunk/serf_private.h

Modified: serf/trunk/outgoing.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/outgoing.c?rev=1709265&r1=1709264&r2=1709265&view=diff
==============================================================================
--- serf/trunk/outgoing.c (original)
+++ serf/trunk/outgoing.c Sun Oct 18 11:51:53 2015
@@ -29,6 +29,11 @@
 
 #include "serf_private.h"
 
+/* forward definitions */
+static apr_status_t read_from_connection(serf_connection_t *conn);
+static apr_status_t write_to_connection(serf_connection_t *conn);
+static apr_status_t hangup_connection(serf_connection_t *conn);
+
 /* cleanup for sockets */
 static apr_status_t clean_skt(void *data)
 {
@@ -725,6 +730,11 @@ static apr_status_t reset_connection(ser
     conn->write_now = 0;
     /* conn->pipelining */
 
+    conn->framing_type = SERF_CONNECTION_FRAMING_TYPE_HTTP1;
+    conn->perform_read = read_from_connection;
+    conn->perform_write = write_to_connection;
+    conn->perform_hangup = hangup_connection;
+
     conn->status = APR_SUCCESS;
 
     /* Let our context know that we've 'reset' the socket already. */
@@ -1449,6 +1459,20 @@ error:
     return status;
 }
 
+/* The connection got reset by the server. On Windows this can happen
+   when all data is read, so just cleanup the connection and open a new one.
+
+   If we haven't had any successful responses on this connection,
+   then error out as it is likely a server issue. */
+static apr_status_t hangup_connection(serf_connection_t *conn)
+{
+    if (conn->completed_responses) {
+        return reset_connection(conn, 1);
+    }
+
+    return SERF_ERROR_ABORTED_CONNECTION;
+}
+
 /* process all events on the connection */
 apr_status_t serf__process_connection(serf_connection_t *conn,
                                       apr_int16_t events)
@@ -1460,7 +1484,7 @@ apr_status_t serf__process_connection(se
      * it before we trigger a reset condition.
      */
     if ((events & APR_POLLIN) != 0) {
-        if ((status = read_from_connection(conn)) != APR_SUCCESS)
+        if ((status = conn->perform_read(conn)) != APR_SUCCESS)
             return status;
 
         /* If we decided to reset our connection, return now as we don't
@@ -1471,15 +1495,8 @@ apr_status_t serf__process_connection(se
         }
     }
     if ((events & APR_POLLHUP) != 0) {
-        /* The connection got reset by the server. On Windows this can happen
-           when all data is read, so just cleanup the connection and open
-           a new one.
-           If we haven't had any successful responses on this connection,
-           then error out as it is likely a server issue. */
-        if (conn->completed_responses) {
-            return reset_connection(conn, 1);
-        }
-        return SERF_ERROR_ABORTED_CONNECTION;
+        /* The connection got reset by the server. */
+        return conn->perform_hangup(conn);
     }
     if ((events & APR_POLLERR) != 0) {
         /* We might be talking to a buggy HTTP server that doesn't
@@ -1530,7 +1547,7 @@ apr_status_t serf__process_connection(se
         return APR_EGENERAL;
     }
     if ((events & APR_POLLOUT) != 0) {
-        if ((status = write_to_connection(conn)) != APR_SUCCESS)
+        if ((status = conn->perform_write(conn)) != APR_SUCCESS)
             return status;
     }
     return APR_SUCCESS;
@@ -1569,6 +1586,9 @@ serf_connection_t *serf_connection_creat
     conn->write_now = 0;
     conn->pipelining = 1;
     conn->framing_type = SERF_CONNECTION_FRAMING_TYPE_HTTP1;
+    conn->perform_read = read_from_connection;
+    conn->perform_write = write_to_connection;
+    conn->perform_hangup = hangup_connection;
 
     /* Create a subpool for our connection. */
     apr_pool_create(&conn->skt_pool, conn->pool);

Modified: serf/trunk/serf_private.h
URL: 
http://svn.apache.org/viewvc/serf/trunk/serf_private.h?rev=1709265&r1=1709264&r2=1709265&view=diff
==============================================================================
--- serf/trunk/serf_private.h (original)
+++ serf/trunk/serf_private.h Sun Oct 18 11:51:53 2015
@@ -408,6 +408,12 @@ struct serf_connection_t {
     /* Write out information now */
     int write_now;
 
+    /* Event callbacks, called from serf__process_connection() to do the actual
+       processing. */
+    apr_status_t(*perform_read)(serf_connection_t *conn);
+    apr_status_t(*perform_write)(serf_connection_t *conn);
+    apr_status_t(*perform_hangup)(serf_connection_t *conn);
+
     /* Configuration shared with buckets and authn plugins */
     serf_config_t *config;
 };


Reply via email to