Diff
Not logged in

Differences From Artifact [d4601d4895]:

To Artifact [97e16d65dc]:


66
67
68
69
70
71
72





73
74






75
76
77
78
79
80

81
82
83
84
85
86
87
66
67
68
69
70
71
72
73
74
75
76
77


78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96







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





-
+







 * Locks are never held when calling the ReadConsole/WriteConsole API's
 * since they may block.
 */

static int gInitialized = 0;

/*
 * INPUT_BUFFER_SIZE is size of buffer passed to ReadConsole in bytes.
 * Note that ReadConsole will only allow reading of line lengths up to the
 * max of 256 and buffer size passed to it. So dropping this below 512
 * means user can type at most 256 chars.
 */
 * Permit CONSOLE_BUFFER_SIZE to be defined on build command for stress test.
 *
#ifndef INPUT_BUFFER_SIZE
#define INPUT_BUFFER_SIZE 8192 /* In bytes, so 4096 chars */
#endif

/*
 * CONSOLE_BUFFER_SIZE is size of storage used in ring buffers.
 * In theory, at least sizeof(WCHAR) but note the Tcl channel bug
 * https://core.tcl-lang.org/tcl/tktview/b3977d199b08e3979a8da970553d5209b3042e9c
 * will cause failures in test suite if close to max input line in the suite.
 */
#ifndef CONSOLE_BUFFER_SIZE
#define CONSOLE_BUFFER_SIZE 8000 /* In bytes */
#define CONSOLE_BUFFER_SIZE 8192 /* In bytes */
#endif

/*
 * Ring buffer for storing data. Actual data is from bufPtr[start]:bufPtr[size-1]
 * and bufPtr[0]:bufPtr[length - (size-start)].
 */
typedef struct RingBuffer {
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149







1150




1151
1152

1153

1154
1155
1156
1157
1158
1159
1160
1161
1148
1149
1150
1151
1152
1153
1154




1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169

1170

1171
1172
1173
1174
1175
1176
1177







-
-
-
-
+
+
+
+
+
+
+

+
+
+
+


+
-
+
-







	    *errorCode = EWOULDBLOCK;
	    numRead = -1;
	    break;
	}

	/*
	 * Blocking read. Just get data from directly from console. There
	 * is a small complication in that we can only read even number
	 * of bytes (wide-character API) and the destination buffer should be
	 * WCHAR aligned. If either condition is not met, we defer to the
	 * reader thread which handles these case rather than dealing with
	 * is a small complication in that
	 * 1. The destination buffer should be WCHAR aligned.
	 * 2. We can only read even number of bytes (wide-character API).
	 * 3. Caller has large enough buffer (else length of line user can
	 *    enter will be limited)
	 * If any condition is not met, we defer to the
	 * reader thread which handles these cases rather than dealing with
	 * them here (which is a little trickier than it might sound.)
	 *
	 * TODO - not clear this block is a useful optimization. bufSize by
	 * default is 4K which is < INPUT_BUFFER_SIZE and will rarely be
	 * increased on stdin.
	 */
	if ((1 & (size_t)bufPtr) == 0 /* aligned buffer */
	    && (1 & bufSize) == 0     /* Even number of bytes */
	    && bufSize > 1         /* Not single byte read */
	    && bufSize > INPUT_BUFFER_SIZE) {
	) {
	    DWORD lastError;
	    Tcl_Size numChars;
	    ReleaseSRWLockExclusive(&handleInfoPtr->lock);
	    lastError = ReadConsoleChars(chanInfoPtr->handle,
					 (WCHAR *)bufPtr,
					 bufSize / sizeof(WCHAR),
					 &numChars);
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648
1649
1646
1647
1648
1649
1650
1651
1652






1653
1654
1655
1656
1657
1658
1659
1660







-
-
-
-
-
-
+







{
    ConsoleHandleInfo *handleInfoPtr = (ConsoleHandleInfo *) arg;
    ConsoleHandleInfo **iterator;
    Tcl_Size inputLen = 0;
    Tcl_Size inputOffset = 0;
    Tcl_Size lastReadSize = 0;
    DWORD sleepTime;
    /*
     * ReadConsole will limit input to the greater of 256 characters
     * and the size of the input buffer. 8.6 used 8192 (4096 chars)
     * and so do we.
     */
    char inputChars[8192];
    char inputChars[INPUT_BUFFER_SIZE];

    /*
     * Keep looping until one of the following happens.
     * - there are no more channels listening on the console
     * - the console handle has been closed
     */