ssl optimize poll when buffered ssl read data
authorAndy Green <andy.green@linaro.org>
Thu, 9 Oct 2014 00:29:22 +0000 (08:29 +0800)
committerAndy Green <andy.green@linaro.org>
Thu, 9 Oct 2014 00:29:22 +0000 (08:29 +0800)
Signed-off-by: Andy Green <andy.green@linaro.org>
lib/lws-plat-unix.c
lib/private-libwebsockets.h
lib/service.c
lib/ssl.c

index b8f209d..a43d57b 100644 (file)
@@ -108,13 +108,27 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms)
        context->service_tid = context->protocols[0].callback(context, NULL,
                                     LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
 
+#ifdef LWS_OPENSSL_SUPPORT
+       /* if we know we have non-network pending data, do not wait in poll */
+       if (context->ssl_flag_buffered_reads)
+               timeout_ms = 0;
+#endif
        n = poll(context->fds, context->fds_count, timeout_ms);
        context->service_tid = 0;
 
+#ifdef LWS_OPENSSL_SUPPORT
+       if (!context->ssl_flag_buffered_reads && n == 0) {
+#else
        if (n == 0) /* poll timeout */ {
+#endif
                libwebsocket_service_fd(context, NULL);
                return 0;
        }
+       
+#ifdef LWS_OPENSSL_SUPPORT
+       /* any more will have to set it fresh this time around */
+       context->ssl_flag_buffered_reads = 0;
+#endif
 
        if (n < 0) {
                if (LWS_ERRNO != LWS_EINTR)
@@ -138,6 +152,11 @@ lws_plat_service(struct libwebsocket_context *context, int timeout_ms)
                if (wsi->ssl && wsi->buffered_reads_pending) {
                        lwsl_debug("wsi %p: forcing POLLIN\n", wsi);
                        context->fds[n].revents |= context->fds[n].events & POLLIN;
+                       if (context->fds[n].revents & POLLIN)
+                               wsi->buffered_reads_pending = 0;
+                       else
+                               /* somebody left with pending SSL read data */
+                               context->ssl_flag_buffered_reads = 1;
                }
 #endif
                if (!context->fds[n].revents)
index 5c20b4c..9c19f22 100755 (executable)
@@ -464,6 +464,7 @@ struct libwebsocket_context {
        int allow_non_ssl_on_ssl_port;
        SSL_CTX *ssl_ctx;
        SSL_CTX *ssl_client_ctx;
+       unsigned int ssl_flag_buffered_reads:1;
 #endif
        struct libwebsocket_protocols *protocols;
        int count_protocols;
index 5565709..f3c0138 100644 (file)
@@ -436,7 +436,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
                if (!(pollfd->revents & LWS_POLLIN))
                        break;
 
-               eff_buf.token_len = lws_ssl_capable_read(context->wsi,
+               eff_buf.token_len = lws_ssl_capable_read(contextwsi,
                                context->service_buffer,
                                               sizeof(context->service_buffer));
                switch (eff_buf.token_len) {
index 120aece..3cdfdea 100644 (file)
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -374,8 +374,10 @@ lws_ssl_capable_read(struct libwebsocket_context *context,
                 * Because these won't signal at the network layer with POLLIN
                 * and if we don't realize, this data will sit there forever
                 */
-               if (n == len && wsi->ssl && SSL_pending(wsi->ssl))
+               if (n == len && wsi->ssl && SSL_pending(wsi->ssl)) {
+                       context->ssl_flag_buffered_reads = 1;
                        wsi->buffered_reads_pending = 1;
+               }
                
                return n;
        }