• doc error?

    From saito@saitology9@gmail.com to comp.lang.tcl on Sun Feb 8 14:05:43 2026
    From Newsgroup: comp.lang.tcl

    I was not expecting this to throw an error. Docs says it should return 0
    or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with "tid"
    and a number.

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Sun Feb 8 20:26:45 2026
    From Newsgroup: comp.lang.tcl

    Am 08.02.2026 um 20:05 schrieb saito:
    I was not expecting this to throw an error. Docs says it should return 0
    or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with "tid"
    and a number.


    Yes, please file a bug report:

    https://core.tcl-lang.org/thread/ticket

    Thanks,
    Harald
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From undroidwish@undroidwish@googlemail.com to comp.lang.tcl on Sun Feb 8 22:40:39 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/26 20:26, Harald Oehlmann wrote:
    Am 08.02.2026 um 20:05 schrieb saito:
    I was not expecting this to throw an error. Docs says it should return
    0 or 1. How would you do this check?

    % package req Thread
    2.8.5

    % thread::exists ""
    invalid thread handle ""

    % thread::exists abc
    invalid thread handle "abc"


    But then this works:

    % thread::exists tid1
    0

    Weird. It looks like the check expects the argument to start with
    "tid" and a number.


    Yes, please file a bug report:

    https://core.tcl-lang.org/thread/ticket

    Honestly am I puzzled. Why should this non-problem deserve a bug report?
    The fact to construct a thread identifier out of blue strings seems to
    me to be a somehow somewhat malicious act. So how can there be any
    expectations on arbitrary generated thread identifiers being error'd?
    Or answered as non existing?

    In other words: the errors thrown on impossible thread identifiers is
    the correct answer for the query on thread existence.

    Finally, IMO please do not create a ticket.

    BR,
    Christian
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From undroidwish@undroidwish@googlemail.com to comp.lang.tcl on Sun Feb 8 22:49:17 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/26 22:40, undroidwish wrote:

    Finally, IMO please do not create a ticket.

    ... and simply live with the fact that some strings are
    impossible thread identifiers, and some not, but don't
    represent existing threads.

    BR,
    Christian
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Sun Feb 8 17:40:30 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/2026 4:53 PM, Robert Heller wrote:
    At Sun, 8 Feb 2026 22:40:39 +0100 undroidwish <undroidwish@googlemail.com> wrote:

    Finally, IMO please do not create a ticket.

    The OP is NOT expecting thread::exists to behave any differently than it does,
    just that thread::exists behavior be completely and accurately documented. Appearently, the documentation is mute as to what thread::exists does when given a string that is not a proper thread id, with the (erronious) *presumption* that it would return 0 (which is in fact NOT what it does). This
    is a *documentation* bug. And the suggested bug report relates to the *documentation*, not the actual code.


    It started like this but it looks like thread::exists does not
    necessarily function 100%. Documentation can fix this easily by
    requiring a certain format for the id's. But then you will be left to
    add extra code on your own which I think is the purpose of thread::exists.


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sun Feb 8 16:01:33 2026
    From Newsgroup: comp.lang.tcl

    On 2/8/2026 2:32 PM, saito wrote:


    If it is important, then it should be documented. You think it is "tid" followed by numbers? Not so. Why is "tidabc" ok here but not "tidxyz"?

    % thread::exists tidabc
    0

    % thread::exists tidxyz
    invalid thread handle "tidxyz"



    The code that checks is,

    static int
    ThreadGetId(interp, handleObj, thrIdPtr)
    Tcl_Interp *interp;
    Tcl_Obj *handleObj;
    Tcl_ThreadId *thrIdPtr;
    {
    const char *thrHandle = Tcl_GetString(handleObj);

    if (sscanf(thrHandle, THREAD_HNDLPREFIX"%p", thrIdPtr) == 1) {
    return TCL_OK;
    }

    Tcl_AppendResult(interp, "invalid thread handle \"",
    thrHandle, "\"", NULL);
    return TCL_ERROR;
    }


    So, it depends on how sscanf treats %p, and in most cases this has to be a valid pointer, usually a hex number, and abc is valid hex, while xyz is not.

    -e

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Mon Feb 9 08:22:21 2026
    From Newsgroup: comp.lang.tcl

    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.

    About "error or not".
    Most "exists" functions in TCL don't throw errors on invalid arguments.
    For example,
    dict exits {} a b
    has thrown an error in an earlier version of TCL.
    This was changed to not throw an error.

    Thanks for all,
    Harald
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Mon Feb 9 11:44:01 2026
    From Newsgroup: comp.lang.tcl

    On 2/9/2026 2:22 AM, Harald Oehlmann wrote:
    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.


    That sounds good. I will try to file the report sometime this week when
    I get the chance.


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Christian Gollwitzer@auriocus@gmx.de to comp.lang.tcl on Mon Feb 9 20:44:13 2026
    From Newsgroup: comp.lang.tcl

    Am 09.02.26 um 08:22 schrieb Harald Oehlmann:
    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.

    About "error or not".
    Most "exists" functions in TCL don't throw errors on invalid arguments.
    For example,
    dict exits {} a b
    has thrown an error in an earlier version of TCL.
    This was changed to not throw an error.

    I tend to agree with the other Christian. If Tcl had types, then the
    argument to thread::exists would be a Thread identifier and there would
    not be a way to pass some artbitrary object to it. The purpose of this function is to see, if a thread identifier - something you got back from thread::create - corresponds to a running thread. If you pass it
    something which is not a thread identifier, than there is a bug in your program.

    Christian
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Robert Heller@heller@deepsoft.com to comp.lang.tcl on Mon Feb 9 20:16:56 2026
    From Newsgroup: comp.lang.tcl

    At Mon, 9 Feb 2026 20:44:13 +0100 Christian Gollwitzer <auriocus@gmx.de> wrote:

    Am 09.02.26 um 08:22 schrieb Harald Oehlmann:
    Hi Chrstian, all,

    I am very happy about the discussion.

    Ihe intention to file a bug report is to have this discussion in a
    ticket and not here. So the discussion may be found later.

    About "error or not".
    Most "exists" functions in TCL don't throw errors on invalid arguments.
    For example,
    dict exits {} a b
    has thrown an error in an earlier version of TCL.
    This was changed to not throw an error.

    I tend to agree with the other Christian. If Tcl had types, then the
    argument to thread::exists would be a Thread identifier and there would
    not be a way to pass some artbitrary object to it. The purpose of this function is to see, if a thread identifier - something you got back from thread::create - corresponds to a running thread. If you pass it
    something which is not a thread identifier, than there is a bug in your program.
    The problem is that this is NOT documented. The documentation should document this behaviour.

    Christian


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    heller@deepsoft.com -- Webhosting Services
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Mon Feb 9 17:47:46 2026
    From Newsgroup: comp.lang.tcl

    On 2/9/2026 2:44 PM, Christian Gollwitzer wrote:
    Am 09.02.26 um 08:22 schrieb Harald Oehlmann:

    If you pass it
    something which is not a thread identifier, than there is a bug in your program.


    In that case, I am afraid we may need a new command to check if
    something is a valid thread identifier, not just a real/active one. I
    get it, internally it makes sense that the id's have a nice logic and
    format to it. I am of the opinion that this detail can remain internal.

    My original question remains: "How would you do this check?" when you
    receive a thread id from an evil user or colleague or simply by mistake?

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Emiliano@emiliano@example.invalid to comp.lang.tcl on Mon Feb 9 21:02:27 2026
    From Newsgroup: comp.lang.tcl

    On Mon, 9 Feb 2026 20:44:13 +0100
    Christian Gollwitzer <auriocus@gmx.de> wrote:

    [...]
    I tend to agree with the other Christian. If Tcl had types, then the argument to thread::exists would be a Thread identifier and there would
    not be a way to pass some artbitrary object to it. The purpose of this function is to see, if a thread identifier - something you got back from thread::create - corresponds to a running thread. If you pass it
    something which is not a thread identifier, than there is a bug in your program.

    Well, I agree with Harald here. The semantics of "exists" subcommands is
    to return true if the thing exists, or false otherwise, without considering *why* it doesn't exists; it doesn't, so return 0. There are plenty of
    examples in Tcl (and Tk):

    # namespace foo::bar doesn't exists
    % info exists foo::bar::baz
    0
    % namespace exists foo::bar::baz
    0
    % namespace ensemble exists foo::bar::baz
    0
    # "foo" is not a valid dictionary
    % dict exists foo a
    0
    # "Nosuchwindow" is not a valid window name
    % package require Tk; winfo exists Nosuchwindow
    0

    Having to test if the handle conforms to certain naming convention and
    only then test whether it exists or not is, IMO, a bug. Not to mention
    that values such as "tidabcXYZ AND SOME NONSENSE", which is an invalid
    thread identifier, will pass the test.

    Regards
    --
    Emiliano <emil.gavilan@gmail.com>
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From undroidwish@undroidwish@googlemail.com to comp.lang.tcl on Tue Feb 10 23:06:14 2026
    From Newsgroup: comp.lang.tcl

    On 2/9/26 23:47, saito wrote:

    ...
    My original question remains: "How would you do this check?" when you receive a thread id from an evil user or colleague or simply by mistake?

    Due to the nature of threads their sheer existence is bound to their
    containing process. Are there real use cases where a thread identifier
    is given to the process' outer world? Yes, I know, some POSIX IPC means
    can be process shared, but those are mutexen and the like, threads not
    so much. Ahem, well there might be the need to kill a thread, but then
    again, the Tcl thread identifier doesn't make sense either, since the
    native thread id is needed which most likely does not equal the Tcl
    thread identifier.

    BR,
    Christian

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Christian Gollwitzer@auriocus@gmx.de to comp.lang.tcl on Wed Feb 11 07:35:55 2026
    From Newsgroup: comp.lang.tcl

    Am 10.02.26 um 23:06 schrieb undroidwish:
    On 2/9/26 23:47, saito wrote:

    ...
    My original question remains: "How would you do this check?" when you
    receive a thread id from an evil user or colleague or simply by mistake?

    Due to the nature of threads their sheer existence is bound to their containing process. Are there real use cases where a thread identifier
    is given to the process' outer world?

    Exactly that was my reasoning. If you pass anything as a thread
    identifier to any of the thread:: functions, and it is not what you got
    from thread::create, then you have a bug in your program. The thread ID
    is an opaque handle and should be treated like a pointer in C. You don't
    write a pointer to a file and read it back later, your program will
    crash. I could only see the need for a sentinel value, like the empty
    string, so that you can initialize a variable.

    The Other Christian


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Ralf Fassel@ralfixx@gmx.de to comp.lang.tcl on Wed Feb 11 10:36:19 2026
    From Newsgroup: comp.lang.tcl

    * Christian Gollwitzer <auriocus@gmx.de>
    | Am 10.02.26 um 23:06 schrieb undroidwish:
    | > On 2/9/26 23:47, saito wrote:
    | >
    | >> ...
    | >> My original question remains: "How would you do this check?" when
    | >> you receive a thread id from an evil user or colleague or simply by
    | >> mistake?
    | > Due to the nature of threads their sheer existence is bound to their
    | > containing process. Are there real use cases where a thread identifier
    | > is given to the process' outer world?

    | Exactly that was my reasoning. If you pass anything as a thread
    | identifier to any of the thread:: functions, and it is not what you
    | got from thread::create, then you have a bug in your program.

    It should be documented, I think that much is undisputed.

    If anyone needs a threadid-safe version (pun intended :-) of thread::exists,

    proc thread_exists_safe {id} {
    return [expr {![catch {thread::exists $id} exists] && $exists}]
    }

    is quickly coded (even without asking ChatGPT)...

    R'
    --- Synchronet 3.21b-Linux NewsLink 1.2