diff options
-rw-r--r-- | generic/tclIO.c | 47 | ||||
-rw-r--r-- | generic/tclIORChan.c | 8 | ||||
-rw-r--r-- | tests/io.test | 185 | ||||
-rw-r--r-- | tests/ioCmd.test | 48 |
4 files changed, 36 insertions, 252 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index d154c77..8e9e346 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -102,30 +102,11 @@ typedef struct CopyState { Tcl_WideInt total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ - int refCount; /* Claim count on the struct */ - int bufInUse; /* Flag to govern access to buffer */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; -static void -PreserveCopyState( - CopyState *csPtr) -{ - csPtr->refCount++; -} - -static void -ReleaseCopyState( - CopyState *csPtr) -{ - if (--csPtr->refCount) { - return; - } - ckfree(csPtr); -} - /* * All static variables used in this file are collected into a single instance * of the following structure. For multi-threaded implementations, there is @@ -9111,13 +9092,9 @@ TclCopyChannel( Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; - csPtr->refCount = 1; - csPtr->bufInUse = 0; inStatePtr->csPtrR = csPtr; - PreserveCopyState(csPtr); outStatePtr->csPtrW = csPtr; - PreserveCopyState(csPtr); if (moveBytes) { return MoveBytes(csPtr); @@ -9403,11 +9380,6 @@ CopyData( /* Encoding control */ int underflow; /* Input underflow */ - if (csPtr->bufInUse) { - return TCL_OK; - } - PreserveCopyState(csPtr); - inChan = (Tcl_Channel) csPtr->readPtr; outChan = (Tcl_Channel) csPtr->writePtr; inStatePtr = csPtr->readPtr->state; @@ -9470,7 +9442,6 @@ CopyData( sizeb = (int) csPtr->toRead; } - csPtr->bufInUse = 1; if (inBinary || sameEncoding) { size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb, !GotFlag(inStatePtr, CHANNEL_NONBLOCKING)); @@ -9526,7 +9497,6 @@ CopyData( TclDecrRefCount(bufObj); bufObj = NULL; } - ReleaseCopyState(csPtr); return TCL_OK; } } @@ -9547,7 +9517,6 @@ CopyData( } else { sizeb = WriteChars(outStatePtr->topChanPtr, buffer, sizeb); } - csPtr->bufInUse = 0; /* * [Bug 2895565]. At this point 'size' still contains the number of @@ -9619,7 +9588,6 @@ CopyData( TclDecrRefCount(bufObj); bufObj = NULL; } - ReleaseCopyState(csPtr); return TCL_OK; } @@ -9642,7 +9610,6 @@ CopyData( TclDecrRefCount(bufObj); bufObj = NULL; } - ReleaseCopyState(csPtr); return TCL_OK; } } /* while */ @@ -9658,7 +9625,7 @@ CopyData( */ total = csPtr->total; - if (cmdPtr && interp && csPtr->cmdPtr) { + if (cmdPtr && interp) { int code; /* @@ -9666,7 +9633,8 @@ CopyData( * arguments. Note that StopCopy frees our saved reference to the * original command obj. */ - cmdPtr = Tcl_DuplicateObj(csPtr->cmdPtr); + + cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); StopCopy(csPtr); Tcl_Preserve(interp); @@ -9694,7 +9662,6 @@ CopyData( } } } - ReleaseCopyState(csPtr); return result; } @@ -10012,16 +9979,10 @@ StopCopy( Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr); Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); TclDecrRefCount(csPtr->cmdPtr); - csPtr->cmdPtr = NULL; } - if (inStatePtr->csPtrR == NULL) { - return; - } - ReleaseCopyState(inStatePtr->csPtrR); inStatePtr->csPtrR = NULL; - ReleaseCopyState(outStatePtr->csPtrW); outStatePtr->csPtrW = NULL; - ReleaseCopyState(csPtr); + ckfree(csPtr); } /* diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index a387410..21c766e 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1601,6 +1601,14 @@ ReflectWatch( mask &= rcPtr->mode; + if (mask == rcPtr->interest) { + /* + * Same old, same old, why should we do something? + */ + + return; + } + rcPtr->interest = mask; /* diff --git a/tests/io.test b/tests/io.test index 783bc75..6b6ad6d 100644 --- a/tests/io.test +++ b/tests/io.test @@ -8003,191 +8003,6 @@ test io-53.17 {[7c187a3773] MBWrite: proper inQueueTail handling} -setup { close $c removeFile out } -result {line 100 line} -test io-53.18 {[32ae34e63a] recursive CopyData} -setup { - proc driver {cmd args} { - variable buffer - variable index - set chan [lindex $args 0] - switch -- $cmd { - initialize { - set index($chan) 0 - set buffer($chan) [encoding convertto utf-8 \ - [string repeat a 100]] - return {initialize finalize watch read} - } - finalize { - unset index($chan) buffer($chan) - return - } - watch { - if {"read" in [lindex $args 1]} { - chan postevent $chan read - } - return - } - read { - set n [lindex $args 1] - set new [expr {$index($chan) + $n}] - set result [string range $buffer($chan) $index($chan) $new-1] - set index($chan) $new - return $result - } - } - } - proc more {c outChan bytes args} { - if {[eof $c]} { - set ::done eof - catch {close $c} - return - } - if {[llength $args]} { - set ::done error - } else { - chan copy $c $outChan -command [list [namespace which more] $c $outChan] - } - } - set c [chan create read [namespace which driver]] - chan configure $c -encoding utf-8 - set out [makeFile {} out] - set outChan [open $out w] - # Different encoding to force use of DoReadChars() - chan configure $outChan -encoding iso8859-1 -} -body { - after 100 {set ::done timeout} - chan copy $c $outChan -size 99 -command [list [namespace which more] $c $outChan] - vwait ::done - set ::done -} -cleanup { - close $outChan - removeFile out - rename driver {} - rename more {} - unset ::done -} -result eof - -test io-53.19 {[32ae34e63a] stop ReflectWatch filtering} -setup { - proc driver {cmd args} { - variable buffer - variable index - set chan [lindex $args 0] - switch -- $cmd { - initialize { - set index($chan) 0 - set buffer($chan) [encoding convertto utf-8 \ - [string repeat a 100]] - return {initialize finalize watch read} - } - finalize { - unset index($chan) buffer($chan) - return - } - watch { - if {"read" in [lindex $args 1]} { - chan postevent $chan read - } - return - } - read { - set n [lindex $args 1] - set new [expr {$index($chan) + $n}] - set result [string range $buffer($chan) $index($chan) $new-1] - set index($chan) $new - return $result - } - } - } - proc more {c outChan bytes args} { - if {[eof $c]} { - set ::done eof - catch {close $c} - return - } - if {[llength $args]} { - set ::done error - } else { - chan copy $c $outChan -size 30 -command [list [namespace which more] $c $outChan] - } - } - set c [chan create read [namespace which driver]] - chan configure $c -encoding utf-8 -buffersize 20 - set out [makeFile {} out] - set outChan [open $out w] - # Different encoding to force use of DoReadChars() - chan configure $outChan -encoding iso8859-1 -} -body { - after 100 {set ::done timeout} - chan copy $c $outChan -size 30 -command [list [namespace which more] $c $outChan] - vwait ::done - set ::done -} -cleanup { - catch {close $outChan} - removeFile out - rename driver {} - rename more {} - unset ::done -} -result eof - -test io-53.20 {[e0a7b3e5f8] DoRead calls to UpdateInterest} -constraints knownBug -setup { - proc driver {cmd args} { - variable buffer - variable index - set chan [lindex $args 0] - switch -- $cmd { - initialize { - set index($chan) 0 - set buffer($chan) [encoding convertto utf-8 \ - [string repeat a 100]] - return {initialize finalize watch read} - } - finalize { - unset index($chan) buffer($chan) - return - } - watch { - if {"read" in [lindex $args 1]} { - chan postevent $chan read - } - return - } - read { - set n [lindex $args 1] - set new [expr {$index($chan) + $n}] - set result [string range $buffer($chan) $index($chan) $new-1] - set index($chan) $new - return $result - } - } - } - proc more {c outChan bytes args} { - if {[eof $c]} { - set ::done eof - catch {close $c} - return - } - if {[llength $args]} { - set ::done error - } else { - chan copy $c $outChan -size 10 -command [list [namespace which more] $c $outChan] - } - } - set c [chan create read [namespace which driver]] - chan configure $c -encoding utf-8 -buffersize 20 - set out [makeFile {} out] - set outChan [open $out w] - # Same encoding to force use of DoRead() - chan configure $outChan -encoding utf-8 -} -body { - after 100 {set ::done timeout} - chan copy $c $outChan -size 10 -command [list [namespace which more] $c $outChan] - vwait ::done - set ::done -} -cleanup { - catch {close $outChan} - removeFile out - rename driver {} - rename more {} - unset ::done -} -result eof test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive diff --git a/tests/ioCmd.test b/tests/ioCmd.test index f66480a..cd89a02 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -1019,7 +1019,7 @@ test iocmd-23.1 {chan read, regular data return} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {read rc* 4096} {watch rc* {}} snarfsnarf} +} -result {{read rc* 4096} {read rc* 4096} snarfsnarf} test iocmd-23.2 {chan read, bad data return, to much} -match glob -body { set res {} proc foo {args} { @@ -1031,7 +1031,7 @@ test iocmd-23.2 {chan read, bad data return, to much} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 {read delivered more than requested}} +} -result {{read rc* 4096} 1 {read delivered more than requested}} test iocmd-23.3 {chan read, for non-readable channel} -match glob -body { set res {} proc foo {args} { @@ -1054,7 +1054,7 @@ test iocmd-23.4 {chan read, error return} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 BOOM!} +} -result {{read rc* 4096} 1 BOOM!} test iocmd-23.5 {chan read, break return is error} -match glob -body { set res {} proc foo {args} { @@ -1066,7 +1066,7 @@ test iocmd-23.5 {chan read, break return is error} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} +} -result {{read rc* 4096} 1 *bad code*} test iocmd-23.6 {chan read, continue return is error} -match glob -body { set res {} proc foo {args} { @@ -1078,7 +1078,7 @@ test iocmd-23.6 {chan read, continue return is error} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} +} -result {{read rc* 4096} 1 *bad code*} test iocmd-23.7 {chan read, custom return is error} -match glob -body { set res {} proc foo {args} { @@ -1090,7 +1090,7 @@ test iocmd-23.7 {chan read, custom return is error} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} +} -result {{read rc* 4096} 1 *bad code*} test iocmd-23.8 {chan read, level is squashed} -match glob -body { set res {} proc foo {args} { @@ -1102,7 +1102,7 @@ test iocmd-23.8 {chan read, level is squashed} -match glob -body { close $c rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} +} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} test iocmd-23.9 {chan read, no data means eof} -match glob -setup { set res {} proc foo {args} { @@ -1118,7 +1118,7 @@ test iocmd-23.9 {chan read, no data means eof} -match glob -setup { close $c rename foo {} unset res -} -result {{read rc* 4096} {watch rc* {}} {} 1} +} -result {{read rc* 4096} {} 1} test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup { set res {} proc foo {args} { @@ -1134,7 +1134,7 @@ test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glo close $c rename foo {} unset res -} -result {{read rc* 4096} {watch rc* {}} {} 0} +} -result {{read rc* 4096} {} 0} test iocmd-23.11 {chan read, close pulls the rug out} -match glob -body { set res {} proc foo {args} { @@ -1448,14 +1448,14 @@ test iocmd-25.10 {chan configure, cgetall, level is ignored} -match glob -body { test iocmd-26.1 {chan configure, set standard option} -match glob -body { set res {} proc foo {args} { - oninit configure; onfinal; track; return + oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return } set c [chan create {r w} foo] note [fconfigure $c -translation lf] close $c rename foo {} set res -} -result {{watch rc* {}} {}} +} -result {{}} test iocmd-26.2 {chan configure, set option, error return} -match glob -body { set res {} proc foo {args} { @@ -1993,7 +1993,7 @@ test iocmd-31.6 {chan postevent, posted events do happen} -match glob -body { close $c rename foo {} set res -} -result {{watch rc* read} {} TOCK {watch rc* read} {} {watch rc* {}}} +} -result {{watch rc* read} {} TOCK {} {watch rc* {}}} test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body { set res {} proc foo {args} {oninit; onfinal; track; return} @@ -2006,7 +2006,7 @@ test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body { close $c rename foo {} set res -} -result {{watch rc* write} {} TOCK {watch rc* write} {} {watch rc* {}}} +} -result {{watch rc* write} {} TOCK {} {watch rc* {}}} test iocmd-31.8 {chan postevent after close throws error} -match glob -setup { proc foo {args} {oninit; onfinal; track; return} proc dummy args { return } @@ -2300,7 +2300,7 @@ test iocmd.tf-23.1 {chan read, regular data return} -match glob -body { } c] rename foo {} set res -} -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} {watch rc* {}} snarfsnarf} +} -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf} test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body { set res {} proc foo {args} { @@ -2315,7 +2315,7 @@ test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body { } c] rename foo {} set res -} -constraints {testchannel thread} -result {{read rc* 4096} {watch rc* {}} 1 {read delivered more than requested}} +} -constraints {testchannel thread} -result {{read rc* 4096} 1 {read delivered more than requested}} test iocmd.tf-23.3 {chan read, for non-readable channel} -match glob -body { set res {} proc foo {args} { @@ -2344,7 +2344,7 @@ test iocmd.tf-23.4 {chan read, error return} -match glob -body { } c] rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 BOOM!} \ +} -result {{read rc* 4096} 1 BOOM!} \ -constraints {testchannel thread} test iocmd.tf-23.5 {chan read, break return is error} -match glob -body { set res {} @@ -2360,7 +2360,7 @@ test iocmd.tf-23.5 {chan read, break return is error} -match glob -body { } c] rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} \ +} -result {{read rc* 4096} 1 *bad code*} \ -constraints {testchannel thread} test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body { set res {} @@ -2376,7 +2376,7 @@ test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body { } c] rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} \ +} -result {{read rc* 4096} 1 *bad code*} \ -constraints {testchannel thread} test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body { set res {} @@ -2392,7 +2392,7 @@ test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body { } c] rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code*} \ +} -result {{read rc* 4096} 1 *bad code*} \ -constraints {testchannel thread} test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body { set res {} @@ -2408,7 +2408,7 @@ test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body { } c] rename foo {} set res -} -result {{read rc* 4096} {watch rc* {}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \ +} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \ -constraints {testchannel thread} test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup { set res {} @@ -2428,7 +2428,7 @@ test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup { } -cleanup { rename foo {} unset res -} -result {{read rc* 4096} {watch rc* {}} {} 1} \ +} -result {{read rc* 4096} {} 1} \ -constraints {testchannel thread} test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup { set res {} @@ -2448,7 +2448,7 @@ test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match } -cleanup { rename foo {} unset res -} -result {{read rc* 4096} {watch rc* {}} {} 0} \ +} -result {{read rc* 4096} {} 0} \ -constraints {testchannel thread} # --- === *** ########################### @@ -3001,7 +3001,7 @@ test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -bod test iocmd.tf-26.1 {chan configure, set standard option} -match glob -body { set res {} proc foo {args} { - oninit configure; onfinal; track; return + oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return } set c [chan create {r w} foo] notes [inthread $c { @@ -3011,7 +3011,7 @@ test iocmd.tf-26.1 {chan configure, set standard option} -match glob -body { } c] rename foo {} set res -} -constraints {testchannel thread} -result {{watch rc* {}} {}} +} -constraints {testchannel thread} -result {{}} test iocmd.tf-26.2 {chan configure, set option, error return} -match glob -body { set res {} proc foo {args} { |