Diff
Not logged in

Differences From Artifact [08d985d5a6]:

To Artifact [dfb886f257]:


857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877



























878
879
880
881
882
883
884
885
857
858
859
860
861
862
863














864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

891
892
893
894
895
896
897







-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-







	    /* A notification event already queued. No point in another. */
	    continue;
	}

	handleInfoPtr = FindConsoleInfo(chanInfoPtr);
	/* Pointer is safe to access as we are holding gConsoleLock */

	if (handleInfoPtr != NULL) {
	    AcquireSRWLockShared(&handleInfoPtr->lock);
	    /* Rememebr channel is read or write, never both */
	    if (chanInfoPtr->watchMask & TCL_READABLE) {
		if (RingBufferLength(&handleInfoPtr->buffer) > 0
		    || handleInfoPtr->lastError != ERROR_SUCCESS) {
		    needEvent = 1; /* Input data available or error/EOF */
		}
	    } else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
		if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
		    needEvent = 1; /* Output space available */
		}
	    }
	    ReleaseSRWLockShared(&handleInfoPtr->lock);
	if (handleInfoPtr == NULL) {
	    /* Stale event */
	    continue;
	}

	needEvent = 0;
	AcquireSRWLockShared(&handleInfoPtr->lock);
	/* Rememeber channel is read or write, never both */
	if (chanInfoPtr->watchMask & TCL_READABLE) {
	    if (RingBufferLength(&handleInfoPtr->buffer) > 0
		|| handleInfoPtr->lastError != ERROR_SUCCESS) {
		needEvent = 1; /* Input data available or error/EOF */
	    }
	    /*
	     * TCL_READABLE watch means someone is looking out for data being
	     * available, let reader thread know. Note channel need not be
	     * ASYNC! (Bug [baa51423c2])
	     */
	    handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
	    WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
	}
	else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
	    if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
		needEvent = 1; /* Output space available */
	    }
	}
	ReleaseSRWLockShared(&handleInfoPtr->lock);
	}

	if (needEvent) {
	    ConsoleEvent *evPtr = (ConsoleEvent *)Tcl_Alloc(sizeof(ConsoleEvent));

	    /* See note above loop why this can be accessed without locks */
	    chanInfoPtr->flags |= CONSOLE_EVENT_QUEUED;
	    chanInfoPtr->numRefs += 1; /* So it does not go away while event