defeat POLLOUT if socket in shutdown wait
[platform/upstream/libwebsockets.git] / lib / libwebsockets.c
index a5cc13c..b4bac9f 100644 (file)
@@ -52,18 +52,12 @@ lws_free_wsi(struct lws *wsi)
 
        lws_free_set_NULL(wsi->rxflow_buffer);
        lws_free_set_NULL(wsi->trunc_alloc);
-       /*
-        * These union members have an ah at the start
-        *
-        *      struct _lws_http_mode_related http;
-        *      struct _lws_http2_related http2;
-        *      struct _lws_header_related hdr;
-        *
-        * basically ws-related union member does not
-        */
-       if (wsi->mode != LWSCM_WS_CLIENT &&
-           wsi->mode != LWSCM_WS_SERVING)
-               lws_free_header_table(wsi);
+
+       if (wsi->u.hdr.ah) {
+               /* we're closing, losing some rx is OK */
+               wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
+               lws_header_table_detach(wsi);
+       }
 
        wsi->context->count_wsi_allocated--;
        lwsl_debug("%s: %p, remaining wsi %d\n", __func__, wsi,
@@ -305,10 +299,11 @@ just_kill_connection:
                n = shutdown(wsi->sock, SHUT_WR);
                if (n)
                        lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO);
-               wsi->state = LWSS_SHUTDOWN;
+
                lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
+               wsi->state = LWSS_SHUTDOWN;
                lws_set_timeout(wsi, PENDING_TIMEOUT_SHUTDOWN_FLUSH,
-                               AWAITING_TIMEOUT);
+                               context->timeout_secs);
                return;
        }
 #endif
@@ -378,7 +373,9 @@ just_kill_connection:
            ((wsi->state_pre_close == LWSS_ESTABLISHED) ||
            (wsi->state_pre_close == LWSS_RETURNED_CLOSE_ALREADY) ||
            (wsi->state_pre_close == LWSS_AWAITING_CLOSE_ACK) ||
-           (wsi->state_pre_close == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
+           (wsi->state_pre_close == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) ||
+           (wsi->mode == LWSCM_WS_CLIENT && wsi->state_pre_close == LWSS_HTTP) ||
+           (wsi->mode == LWSCM_WS_SERVING && wsi->state_pre_close == LWSS_HTTP))) {
                lwsl_debug("calling back CLOSED\n");
                wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED,
                                        wsi->user_space, NULL, 0);
@@ -411,10 +408,12 @@ just_kill_connection:
        wsi->socket_is_permanently_unusable = 1;
 
 #ifdef LWS_USE_LIBUV
-       /* libuv has to do his own close handle processing asynchronously */
-       lws_libuv_closehandle(wsi);
+       if (LWS_LIBUV_ENABLED(context)) {
+               /* libuv has to do his own close handle processing asynchronously */
+               lws_libuv_closehandle(wsi);
 
-       return;
+               return;
+       }
 #endif
 
        lws_close_free_wsi_final(wsi);
@@ -926,18 +925,39 @@ lws_ensure_user_space(struct lws *wsi)
 
 LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)
 {
+       time_t o_now = time(NULL);
        unsigned long long now;
+       struct tm *ptm = NULL;
        char buf[300];
+#ifndef WIN32
+       struct tm tm;
+#endif
        int n;
 
+#ifdef WIN32
+       ptm = localtime(&o_now);
+#else
+       if (localtime_r(&o_now, &tm))
+               ptm = &tm;
+#endif
        buf[0] = '\0';
        for (n = 0; n < LLL_COUNT; n++) {
                if (level != (1 << n))
                        continue;
                now = time_in_microseconds() / 100;
-               sprintf(buf, "[%llu:%04d] %s: ",
-                       (unsigned long long) now / 10000,
-                       (int)(now % 10000), log_level_names[n]);
+               if (ptm)
+                       sprintf(buf, "[%04d/%02d/%02d %02d:%02d:%02d:%04d] %s: ",
+                               ptm->tm_year + 1900,
+                               ptm->tm_mon,
+                               ptm->tm_mday,
+                               ptm->tm_hour,
+                               ptm->tm_min,
+                               ptm->tm_sec,
+                               (int)(now % 10000), log_level_names[n]);
+               else
+                       sprintf(buf, "[%llu:%04d] %s: ",
+                                       (unsigned long long) now / 10000,
+                                       (int)(now % 10000), log_level_names[n]);
                break;
        }