Tcl UDP

View Ticket
Login

View Ticket

Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2018 Conference, Houston/TX, US, Oct 15-19
Send your abstracts to tclconference@googlegroups.com or submit via the online form
by Aug 20.
Ticket Hash: b3905a822661d7ccb060926e81b832198ed415b5
Title: Code Not Thread-Safe
Status: Open Type: Code_Defect
Severity: Critical Priority:
Subsystem: Resolution:
Last Modified: 2021-04-12 19:42:27
Version Found In: 1.0.11
User Comments:
anonymous added on 2021-04-12 19:42:27:

The extension crashes when used in multiple threads. The problem is in UDP_CheckProc when it is determining whether it should read the socket. If there are multiple threads, the order in which the threads call this function is not deterministic, so it is possible that the wrong thread will read the socket.

The solution is to verify the correct thread by changing:

    if (statePtr->packetNum > 0) {
to:
    if (statePtr->packetNum > 0 && statePtr->threadId == Tcl_GetCurrentThread()) {
Here is a script that demonstrates the problem. The main thread reads a socket and a child thread writes a socket:
    package require udp
    package require Thread
    
    proc handleRead {chan} {
        set data [read $chan]
        puts "received [string length $data] byte(s)"
    }
    
    set chan [udp_open]
    set port [fconfigure $chan -myport]
    fileevent $chan readable [list handleRead $chan]
    
    set tid [::thread::create]
    ::thread::send $tid "set port $port"
    ::thread::send $tid {
        package require udp
        set chan [udp_open]
        fconfigure $chan -remote [list localhost $port] -buffering none
    }
    
    while 1 {
        ::thread::send $tid {puts -nonewline $chan A}
        update
    }