Tcl Source Code

View Ticket
Bounty program for improvements to Tcl and certain Tcl packages.
Ticket UUID: c6ed4acfd8ba465a8e6681297b81b995acfa7acc
Title: Win: failing async socket connect and other sync socket connect hangs
Type: Bug Version: 8.6.3
Submitter: oehhar Created on: 2014-12-04 09:10:48
Subsystem: 25. Channel System Assigned To: oehhar
Priority: 5 Medium Severity: Critical
Status: Closed Last Modified: 2014-12-07 12:26:00
Resolution: Fixed Closed By: oehhar
    Closed on: 2014-12-07 12:26:00

Chris Shults reported by private E-Mail the following bug:

  • open a server socket to port A
  • open an async client socket to port B, which will fail, as it has no server on
  • open a sync client socket to the server socket

TCL hangs.

Demo script:

#This works in:
#but is broken in:
proc read_sock {channel} {puts [chan read $channel]}

proc accept {channel address port} {
	puts "accept $channel $address $port"
	chan configure $channel -blocking no -buffering none -encoding iso8859-1 -translation binary
	chan event $channel readable "read_sock $channel"

set ssock [socket -server accept 9902]

proc connection_result {channel} {
	puts -nonewline "connection_result: "
	if {[chan configure $channel -error] == ""} {
		puts connected
	} else {
		puts "not connected"
		chan event $channel readable {}
	chan event $channel writable {}

set csock1 [socket -async localhost 9903]
chan configure $csock1 -blocking no -buffering none -encoding iso8859-1 -translation binary
chan event $csock1 readable "read_sock $csock1"
chan event $csock1 writable "connection_result $csock1"

#connect up a client prior to entering the vwait
set csock2 [socket localhost 9902]
chan configure $csock2 -blocking no -buffering none -encoding iso8859-1 -translation binary
chan event $csock2 readable "read_sock $csock2"

after 10000 {puts "This message will never appear"}

vwait forever

when I start wish -f with the upper script, it stalls

User Comments: oehhar added on 2014-12-07 12:26:00:

The patch solves the issue for me and is quite critical.

It will basically make any async socket connect hang when there is already a socket connection present.

Test 14.18 added to check this condition, test suite will hang if patch is not present.

TCL 8.5.17 is not affected by the issue.

Thanks to A.P. Nadkarni finding the issue.

Bug closed, Harald

oehhar added on 2014-12-06 18:47:48:

Thank you for the good catch. This issue should also be in TCl8.5 as it is part of a bug fix:

Bug 336441ed59 happened as follows:

  • A socket was opened and this open was returned to the framework
  • The callback that the socket connected or failed was called by the OS. This was ignored, as the freshly opened socket was not jet in the tsd list
  • The framework registers the socket into the tsd list. This is to late, as the callback already passed.

As a consequence, I buffer a freshly created tsd pointer in a global memory to have it in the callback. This made a couple of workarounds unnecessary and was considered as effective by Andreas Kupries.

I will check tomorrow, if the issue persists with this catch.

Thank you very much. It is good not to feel so much alone...


apnadkarni added on 2014-12-06 11:24:23:

I've checked in a fix [0658e05c4adb40fec2b80e491ad9d0d6fdfb15dc|0658e05c4a] for an obvious typo/bug that should fix the above.

Harald, please review as I haven't completely understood the logic in TcpConnect. The above fix is definitely needed but not sure if anything else needs to be fixed.