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
 * Locks are never held when calling the ReadConsole/WriteConsole API's
 * since they may block.
 */

static int gInitialized = 0;

/*





 * Permit CONSOLE_BUFFER_SIZE to be defined on build command for stress test.


 *


 * 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 */
#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 {







>
>
>
>
>
|
>
>
|
>
>





|







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.
 */
#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 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
	    *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
	 * them here (which is a little trickier than it might sound.)




	 */
	if ((1 & (size_t)bufPtr) == 0 /* aligned buffer */

	    && bufSize > 1         /* Not single byte read */
	) {
	    DWORD lastError;
	    Tcl_Size numChars;
	    ReleaseSRWLockExclusive(&handleInfoPtr->lock);
	    lastError = ReadConsoleChars(chanInfoPtr->handle,
					 (WCHAR *)bufPtr,
					 bufSize / sizeof(WCHAR),
					 &numChars);







|
|
>
>
>
|
|

>
>
>
>


>
|
<







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
	 * 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 > 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
{
    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];

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








<
<
<
<
<
|







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;





    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
     */