0

i have a tcl script used for test automation (with CarMaker ScriptControl interface)

In the script i am calling a proc where some code is executed that may take a few milliseconds before it returns. However, if at a certain point in this proc it gets called again, the second call will fail and cause an error.

I have no control about when the proc will be called, because the calls come from another application. What i am searching for is a way to prevent a parallel call to the function happening while a certain part of my code is being executed.

Something like this:

proc MyProc {args} {
    #Execute Code
    set val 0

    #---this part should not be interrupt
    #Execute non interrupt Code
    RegisterQuantities ($names)
    Foreach name {
        ReadQuantity $name
    }
    #------------------------------------

    return val
}

The calls come from a realtime PC that

S Schulze
  • 127
  • 9
  • You need to be more specific: What is the long-process invocation exactly? `exec`'ing somewhere, a C-implemented Tcl command? Within the same script execution, your re-entrance issue cannot occur (the script will just block for however long it takes). Or, if the `long_process` call is somehow non-blocking (which it isn't, according to your description). It can only occur when the entire script is executed as a different, second process (one `tclsh` execution of the script being outrun by a second of the same script). – mrcalvin Jun 05 '19 at 15:31
  • If this was the case, Donal's answer would not help (the mode variable is not seen beyond one script execution). – mrcalvin Jun 05 '19 at 15:33
  • I udated the code a bot to bettter show what os happening. The calls come from a simulation that runs in a realtime environment.The proc registers values to read from it and then reads them in a loop. If a second call comes between registering and reading the secon call to Regisster will fail and i get an error trying to read them. After the second call returns the first continues and finishes wothout error. – S Schulze Jun 06 '19 at 20:54
  • The missing piece is how exactly calls to `MyProc` come to existence? How is the script with its proc executed exactly? I am aware that you mention `CarMaker` and its `ScriptControl`, but unless someone with background info on the innerworkings of `CarMaker` (there is no documentation available w/o having bought the product) steps up, none of us will be able to help. – mrcalvin Jun 09 '19 at 10:50

1 Answers1

1

The simplest way of doing this is to create a global variable that says whether the code has reached the point where the procedure may be usefully called:

variable ready_for_call 0

proc ReadyForCall {} {
    variable ready_for_call
    set ready_for_call 1
}

proc MyProc {args} {
    variable ready_for_call
    if {!$ready_for_call} {
        # I don't know if you want a warning, or an error, or silent ignoring
        puts stderr "WARNING: called MyProc too early"
        # You might need to return a dummy value here; the default is an empty string
        return
    }
    #Execute Code
    ...
}

Then all you need to do is call ReadyForCall at the point where the command becomes callable (which you can probably characterise fairly well).

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • Thank you for this answer. I will use this to display a more meaningful error message, so the tester knows whats going on. Unfortunately it still breaks the test though – S Schulze Jun 06 '19 at 21:02