]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - windows/winhandl.c
lz77_compress: change scope of variable 'hash'.
[PuTTY.git] / windows / winhandl.c
index d81054f36414c355b205ae1a612ab86733e1d08d..cfd6298747e6f1805b087509ff8e56d50931a274 100644 (file)
@@ -115,7 +115,7 @@ static DWORD WINAPI handle_input_threadfunc(void *param)
     struct handle_input *ctx = (struct handle_input *) param;
     OVERLAPPED ovl, *povl;
     HANDLE oev;
-    int readret, readlen;
+    int readret, readlen, finished;
 
     if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
        povl = &ovl;
@@ -165,18 +165,20 @@ static DWORD WINAPI handle_input_threadfunc(void *param)
            (ctx->flags & HANDLE_FLAG_IGNOREEOF))
            continue;
 
+        /*
+         * If we just set ctx->len to 0, that means the read operation
+         * has returned end-of-file. Telling that to the main thread
+         * will cause it to set its 'defunct' flag and dispose of the
+         * handle structure at the next opportunity, in which case we
+         * mustn't touch ctx at all after the SetEvent. (Hence we do
+         * even _this_ check before the SetEvent.)
+         */
+        finished = (ctx->len == 0);
+
        SetEvent(ctx->ev_to_main);
 
-       if (!ctx->len) {
-            /*
-             * The read operation has returned end-of-file. Telling
-             * that to the main thread will cause it to set its
-             * 'defunct' flag and dispose of the handle structure at
-             * the next opportunity, so we must not touch ctx at all
-             * after this.
-             */
+       if (finished)
            break;
-        }
 
        WaitForSingleObject(ctx->ev_from_main, INFINITE);
        if (ctx->done) {
@@ -409,9 +411,9 @@ static int handle_cmp_evtomain(void *av, void *bv)
     struct handle *a = (struct handle *)av;
     struct handle *b = (struct handle *)bv;
 
-    if ((unsigned)a->u.g.ev_to_main < (unsigned)b->u.g.ev_to_main)
+    if ((uintptr_t)a->u.g.ev_to_main < (uintptr_t)b->u.g.ev_to_main)
        return -1;
-    else if ((unsigned)a->u.g.ev_to_main > (unsigned)b->u.g.ev_to_main)
+    else if ((uintptr_t)a->u.g.ev_to_main > (uintptr_t)b->u.g.ev_to_main)
        return +1;
     else
        return 0;
@@ -422,9 +424,9 @@ static int handle_find_evtomain(void *av, void *bv)
     HANDLE *a = (HANDLE *)av;
     struct handle *b = (struct handle *)bv;
 
-    if ((unsigned)*a < (unsigned)b->u.g.ev_to_main)
+    if ((uintptr_t)*a < (uintptr_t)b->u.g.ev_to_main)
        return -1;
-    else if ((unsigned)*a > (unsigned)b->u.g.ev_to_main)
+    else if ((uintptr_t)*a > (uintptr_t)b->u.g.ev_to_main)
        return +1;
     else
        return 0;
@@ -531,7 +533,7 @@ void handle_write_eof(struct handle *h)
      * direction!
      */
     assert(h->type == HT_OUTPUT);
-    if (!h->u.o.outgoingeof == EOF_NO) {
+    if (h->u.o.outgoingeof == EOF_NO) {
         h->u.o.outgoingeof = EOF_PENDING;
         handle_try_output(&h->u.o);
     }
@@ -577,17 +579,18 @@ static void handle_destroy(struct handle *h)
 
 void handle_free(struct handle *h)
 {
-    /*
-     * If the handle is currently busy, we cannot immediately free
-     * it. Instead we must wait until it's finished its current
-     * operation, because otherwise the subthread will write to
-     * invalid memory after we free its context from under it.
-     */
     assert(h && !h->u.g.moribund);
-    if (h->u.g.busy) {
-       /*
-        * Just set the moribund flag, which will be noticed next
-        * time an operation completes.
+    if (h->u.g.busy && h->type != HT_FOREIGN) {
+        /*
+         * If the handle is currently busy, we cannot immediately free
+         * it, because its subthread is in the middle of something.
+         * (Exception: foreign handles don't have a subthread.)
+         *
+         * Instead we must wait until it's finished its current
+         * operation, because otherwise the subthread will write to
+         * invalid memory after we free its context from under it. So
+         * we set the moribund flag, which will be noticed next time
+         * an operation completes.
         */
        h->u.g.moribund = TRUE;
     } else if (h->u.g.defunct) {