]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - windows/winhandl.c
Remove spurious -shareexists reference in Plink docs.
[PuTTY.git] / windows / winhandl.c
index d81054f36414c355b205ae1a612ab86733e1d08d..b4d508b0ef30f02501223e8e3373b332631853fb 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) {
@@ -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) {