commit 9074d6d2e8644a77fba1573bc0ec594e92899ee6
parent 4c3d16c35ece22321f7a2b133e56e41437d60052
Author: Andrey Uzunov <andrey.uzunov@gmail.com>
Date: Fri, 5 Jul 2013 23:08:31 +0000
spdy: TCP_CORK added for io_raw
Diffstat:
8 files changed, 140 insertions(+), 5 deletions(-)
diff --git a/src/microspdy/io.c b/src/microspdy/io.c
@@ -64,6 +64,8 @@ SPDYF_io_set_session(struct SPDY_Session *session, enum SPDY_IO_SUBSYSTEM io_sub
session->fio_is_pending = &SPDYF_openssl_is_pending;
session->fio_recv = &SPDYF_openssl_recv;
session->fio_send = &SPDYF_openssl_send;
+ session->fio_before_write = &SPDYF_openssl_before_write;
+ session->fio_after_write = &SPDYF_openssl_after_write;
break;
case SPDY_IO_SUBSYSTEM_RAW:
@@ -72,6 +74,8 @@ SPDYF_io_set_session(struct SPDY_Session *session, enum SPDY_IO_SUBSYSTEM io_sub
session->fio_is_pending = &SPDYF_raw_is_pending;
session->fio_recv = &SPDYF_raw_recv;
session->fio_send = &SPDYF_raw_send;
+ session->fio_before_write = &SPDYF_raw_before_write;
+ session->fio_after_write = &SPDYF_raw_after_write;
break;
case SPDY_IO_SUBSYSTEM_NONE:
diff --git a/src/microspdy/io.h b/src/microspdy/io.h
@@ -163,6 +163,31 @@ typedef int
/**
+ * Called just before frames are about to be processed and written
+ * to the socket.
+ *
+ * @param session
+ * @return SPDY_NO if writing must not happen in the call;
+ * SPDY_YES otherwise
+ */
+typedef int
+(*SPDYF_IOBeforeWrite) (struct SPDY_Session *session);
+
+
+/**
+ * Called just after frames have been processed and written
+ * to the socket.
+ *
+ * @param session
+ * @param was_written has the same value as the write function for the
+ * session will return
+ * @return returned value will be used by the write function to return
+ */
+typedef int
+(*SPDYF_IOAfterWrite) (struct SPDY_Session *session, int was_written);
+
+
+/**
* Sets callbacks for the daemon with regard to the IO subsystem.
*
* @param daemon
diff --git a/src/microspdy/io_openssl.c b/src/microspdy/io_openssl.c
@@ -253,3 +253,21 @@ SSL_pending() takes into account only bytes from the TLS/SSL record that is curr
*/
return SSL_pending(session->io_context) > 0 ? SPDY_YES : SPDY_NO;
}
+
+
+int
+SPDYF_openssl_before_write(struct SPDY_Session *session)
+{
+ (void)session;
+
+ return SPDY_YES;
+}
+
+
+int
+SPDYF_openssl_after_write(struct SPDY_Session *session, int was_written)
+{
+ (void)session;
+
+ return was_written;
+}
diff --git a/src/microspdy/io_openssl.h b/src/microspdy/io_openssl.h
@@ -139,4 +139,28 @@ SPDYF_openssl_send(struct SPDY_Session *session,
int
SPDYF_openssl_is_pending(struct SPDY_Session *session);
+
+/**
+ * Nothing.
+ *
+ * @param session
+ * @return SPDY_NO if writing must not happen in the call;
+ * SPDY_YES otherwise
+ */
+int
+SPDYF_openssl_before_write(struct SPDY_Session *session);
+
+
+/**
+ * Nothing.
+ *
+ * @param session
+ * @param was_written has the same value as the write function for the
+ * session will return
+ * @return returned value will be used by the write function to return
+ */
+int
+SPDYF_openssl_after_write(struct SPDY_Session *session, int was_written);
+
+
#endif
diff --git a/src/microspdy/io_raw.c b/src/microspdy/io_raw.c
@@ -154,3 +154,31 @@ SPDYF_raw_is_pending(struct SPDY_Session *session)
return SPDY_NO;
}
+
+
+int
+SPDYF_raw_before_write(struct SPDY_Session *session)
+{
+ int val = 1;
+ int ret;
+
+ ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_CORK, &val, (socklen_t)sizeof(val));
+ if(-1 == ret)
+ SPDYF_DEBUG("WARNING: Couldn't set the new connection to TCP_CORK");
+
+ return SPDY_YES;
+}
+
+
+int
+SPDYF_raw_after_write(struct SPDY_Session *session, int was_written)
+{
+ int val = 0;
+ int ret;
+
+ ret = setsockopt(session->socket_fd, IPPROTO_TCP, TCP_CORK, &val, (socklen_t)sizeof(val));
+ if(-1 == ret)
+ SPDYF_DEBUG("WARNING: Couldn't unset the new connection to TCP_CORK");
+
+ return was_written;
+}
diff --git a/src/microspdy/io_raw.h b/src/microspdy/io_raw.h
@@ -132,4 +132,27 @@ SPDYF_raw_send(struct SPDY_Session *session,
int
SPDYF_raw_is_pending(struct SPDY_Session *session);
+
+/**
+ * Sets TCP_CORK.
+ *
+ * @param session
+ * @return SPDY_NO if writing must not happen in the call;
+ * SPDY_YES otherwise
+ */
+int
+SPDYF_raw_before_write(struct SPDY_Session *session);
+
+
+/**
+ * Unsets TCP_CORK.
+ *
+ * @param session
+ * @param was_written has the same value as the write function for the
+ * session will return
+ * @return returned value will be used by the write function to return
+ */
+int
+SPDYF_raw_after_write(struct SPDY_Session *session, int was_written);
+
#endif
diff --git a/src/microspdy/session.c b/src/microspdy/session.c
@@ -868,6 +868,9 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame)
if(SPDY_SESSION_STATUS_CLOSING == session->status)
return SPDY_NO;
+
+ if(SPDY_NO == session->fio_before_write(session))
+ return SPDY_NO;
for(i=0;
only_one_frame
@@ -935,7 +938,7 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame)
//on respones with callbacks it is possible that their is no
//data available
if(0 == session->write_buffer_size)//nothing to write
- {
+ {
if(response_queue != session->response_queue_head)
{
//the handler modified the queue
@@ -946,12 +949,12 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame)
//no need to try the same frame again
break;
}
- }
+ }
}
session->last_activity = SPDYF_monotonic_time();
- //actual write to the TLS socket
+ //actual write to the IO
bytes_written = session->fio_send(session,
session->write_buffer + session->write_buffer_beginning,
session->write_buffer_offset - session->write_buffer_beginning);
@@ -1021,8 +1024,8 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame)
&& NULL == session->response_queue_head)
session->status = SPDY_SESSION_STATUS_CLOSING;
-
- return i>0 ? SPDY_YES : SPDY_NO;
+ //return i>0 ? SPDY_YES : SPDY_NO;
+ return session->fio_after_write(session, i>0);
}
diff --git a/src/microspdy/structures.h b/src/microspdy/structures.h
@@ -684,6 +684,16 @@ struct SPDY_Session
SPDYF_IOIsPending fio_is_pending;
/**
+ * Function to call before writing set of frames.
+ */
+ SPDYF_IOBeforeWrite fio_before_write;
+
+ /**
+ * Function to call after writing set of frames.
+ */
+ SPDYF_IOAfterWrite fio_after_write;
+
+ /**
* Number of bytes that the lib must ignore immediately after they
* are read from the TLS socket without adding them to the read buf.
* This is needed, for instance, when receiving frame bigger than