The enum ForwardedOperation lists the actions which can be forwarded from channel thread to handler thread. The structures matching ForwardParam* are the containers for each operation's arguments, with ForwardParamBase the 'Base class', so to speak. The structure ForwardingEvent is a sub-class of "Tcl_Event" carrying all the information of a forwarded operation, i.e. operation, reference to arguments, reference to result. The latter is handled by structure ForwardingResult This contains not only the basic result information (of the forward itself, not of the forwarded operation) but also management data about the involved threads, and the condition variable to wait on. It also refers back to the ForwardingEvent it belongs to. (evPtr->param, and rPtr->evPtr) (The first is where the crash happens with) The result structures are linked together in a double-linked list starting in forwardList Access to this variable is protected by the rtForwardMutex The ForwardingEvent's, which refer to ForwardingResults, are in their own list, the event list managed by Tcl. Functions acessing forwardList, or otherwise relevant are (1) DeleteReflectedTransformMap() Handles only elements whose destination is the current interpreter. FResults are detached from their FEvents and vice versa. This sets the respective pointers to NULL (i.e. evPtr->param) The FEvent originators = FResult receivers are woken up with a failure note. (2) DeleteThreadReflectedTransformMap() As above, with slightly different filter. Handles only elements whose destination thread is the current thread. (3) ForwardOpToOwnerThread() The function run by the channel thread to transmit an FEvent over to the handler thread. Creates FEVents. Uses (4) for execution. Creates and enqueues FResults. Makes FEvent and FResult refer to each other. Queues the event, wakes up the handler thread to process its events. Waits on the condition variable of the FResult. This blocks the channel thread. Dequeues the FResult after reception. Creates and tears down a thread exit handler (5) on itself (channel thread). (4) ForwardProc() Invoked by Tcl for an FEvent, in the handler thread. Performs the operation, if not canceled (*). At the end pushes the result back via FResult, waking up the originator (3). (*) I.e. when the FEvent got detached from it FResult. (5) SrcExitProc() Thread exit handler, on the originating thread, for the FEvent in flight. Added and removed by (3), before and after. Detaches FEvent/FResult, wakes the receiver (possibly gone?!) for cleanup. The crash seems to happen in (2), for an FResult which is already detached from its FEvent. Maybe due to (5) ? But why would that not always happen ?