Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch dgp-flush-channel Excluding Merge-Ins
This is equivalent to a diff from fb90b0f1fd to b7bbbbc6ed
|
2014-05-28
| ||
| 18:58 | Refinements of FlushChannel() and its callers. Notably includes removal of the flag BUFFER_READY. check-in: 0ddf09e8bd user: dgp tags: core-8-5-branch | |
| 18:49 | Update comment to explain assumptions. Closed-Leaf check-in: b7bbbbc6ed user: dgp tags: dgp-flush-channel | |
| 18:24 | Further simplifications to FlushChannel(). This makes clear the BUFFER_READY flag serves no necessa... check-in: d9e66fbb28 user: dgp tags: dgp-flush-channel | |
|
2014-05-27
| ||
| 13:28 | Move code that can only matter in the first loop iteration out of the loop. check-in: 38257b5296 user: dgp tags: dgp-flush-channel | |
|
2014-05-24
| ||
| 19:56 | Comment out lines of test io-53.4 that appear to do nothing of any value. check-in: fb90b0f1fd user: dgp tags: core-8-5-branch | |
|
2014-05-23
| ||
| 17:17 | Followup on [72c54e1659]. Removed unused variable. check-in: 9f7e74b65a user: andreask tags: core-8-5-branch | |
Changes to generic/tclIO.c.
| ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | + | * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Contributions from Don Porter, NIST, 2014. (not subject to US copyright) * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #undef NDEBUG #include "tclInt.h" #include "tclIO.h" #include <assert.h> /* * For each channel handler registered in a call to Tcl_CreateChannelHandler, * there is one record of the following type. All of records for a specific |
| ︙ | |||
280 281 282 283 284 285 286 | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | - + | #define SpaceLeft(bufPtr) ((bufPtr)->bufLength - (bufPtr)->nextAdded) #define IsBufferReady(bufPtr) ((bufPtr)->nextAdded > (bufPtr)->nextRemoved) #define IsBufferEmpty(bufPtr) ((bufPtr)->nextAdded == (bufPtr)->nextRemoved) |
| ︙ | |||
1144 1145 1146 1147 1148 1149 1150 | 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 | - - - - - - - - - |
CheckForStdChannelsBeingClosed(chan);
/*
* If the refCount reached zero, close the actual channel.
*/
if (statePtr->refCount <= 0) {
|
| ︙ | |||
2486 2487 2488 2489 2490 2491 2492 | 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 | - - - + - - - + - - - - - - + + + + + + + + + + - - + - - + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + - |
Channel *chanPtr, /* The channel to flush on. */
int calledFromAsyncFlush) /* If nonzero then we are being called from an
* asynchronous flush callback. */
{
ChannelState *statePtr = chanPtr->state;
/* State of the channel stack. */
ChannelBuffer *bufPtr; /* Iterates over buffered output queue. */
|
| ︙ | |||
2668 2669 2670 2671 2672 2673 2674 | 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 | - + + + - + + + + + + + | /* * When we get an error we throw away all the output currently * queued. */ DiscardOutputQueued(statePtr); ReleaseChannelBuffer(bufPtr); |
| ︙ | |||
3247 3248 3249 3250 3251 3252 3253 | 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 | - - - - - - - - |
statePtr->closeCbPtr = cbPtr->nextPtr;
(cbPtr->proc)(cbPtr->clientData);
ckfree((char *) cbPtr);
}
ResetFlag(statePtr, CHANNEL_INCLOSE);
|
| ︙ | |||
3665 3666 3667 3668 3669 3670 3671 | 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 | - + - - - + + + + + + + + + + |
/* Prevent read attempts on a closed channel */
DiscardInputQueued(chanPtr->state, 0);
Tcl_SetErrno(EINVAL);
return -1;
}
if ((chanPtr->typePtr->seekProc != NULL)
&& (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) {
|
| ︙ | |||
3850 3851 3852 3853 3854 3855 3856 | 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 | - |
needNlFlush = 0;
}
}
ReleaseChannelBuffer(bufPtr);
}
if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) ||
(needNlFlush && GotFlag(statePtr, CHANNEL_LINEBUFFERED)))) {
|
| ︙ | |||
5969 5970 5971 5972 5973 5974 5975 | 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 | - - - - - - - - |
chanPtr = statePtr->topChanPtr;
if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
return -1;
}
|
| ︙ | |||
6116 6117 6118 6119 6120 6121 6122 | 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 | - - + + - |
/*
* See if we can fill an existing buffer. If we can, read only as much as
* will fit in it. Otherwise allocate a new buffer, add it to the input
* queue and attempt to fill it to the max.
*/
bufPtr = statePtr->inQueueTail;
|
| ︙ | |||
6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 | 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 | + + |
if (statePtr->inQueueTail == NULL) {
statePtr->inQueueHead = bufPtr;
} else {
statePtr->inQueueTail->nextPtr = bufPtr;
}
statePtr->inQueueTail = bufPtr;
} else {
toRead = SpaceLeft(bufPtr);
}
PreserveChannelBuffer(bufPtr);
nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead);
if (nread < 0) {
result = Tcl_GetErrno();
|
| ︙ | |||
6288 6289 6290 6291 6292 6293 6294 | 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 | - - - - - - - - - |
}
ResetFlag(statePtr, CHANNEL_NONBLOCKING);
if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
}
}
|
| ︙ | |||
8821 8822 8823 8824 8825 8826 8827 | 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 | - + |
if (GotFlag(statePtr, CHANNEL_EOF)
&& (bufPtr == NULL || IsBufferEmpty(bufPtr))) {
break;
}
/* If there is no full buffer, attempt to create and/or fill one. */
|
| ︙ | |||
10376 10377 10378 10379 10380 10381 10382 | 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 | - |
#define ChanFlag(chr,bit) (buf[i++] = ((flags & (bit)) ? (chr) : '_'))
ChanFlag('r', TCL_READABLE);
ChanFlag('w', TCL_WRITABLE);
ChanFlag('n', CHANNEL_NONBLOCKING);
ChanFlag('l', CHANNEL_LINEBUFFERED);
ChanFlag('u', CHANNEL_UNBUFFERED);
|
| ︙ |
Changes to generic/tclIO.h.
| ︙ | |||
223 224 225 226 227 228 229 | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | - - - - - | #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in nonblocking * mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ |
| ︙ |
Changes to tests/io.test.
| ︙ | |||
2782 2783 2784 2785 2786 2787 2788 | 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 | - + |
set r
} "hello\nbye\nstrange\n"
test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac fileevent} {
variable c 0
variable x running
set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
proc writelots {s l} {
|
| ︙ | |||
2813 2814 2815 2816 2817 2818 2819 | 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 | - + |
vwait [namespace which -variable x]
fconfigure $cs -blocking off
writelots $cs $l
close $cs
close $ss
vwait [namespace which -variable x]
set c
|
| ︙ |