#2796 CRITICAL_SECTION masterLock not initialized

obsolete: 8.5a1
closed-accepted
8
2004-07-19
2004-07-09
No

Tcl version - current and all inspected - seems to
be a problem all the way back to introduction of
tclWinThrd.c so all v8.0 onwards

OS - Windows only problem, and only if Tcl interpreters
are not created (ie using tcl as a C library)

When Tcl is used as a library (e.g. for utf-8 or regexp
functions) on the Windows platform and TCL_THREADS
is defined during the build of Tcl, the functions will
produce a seg fault when the
MASTER_LOCK
macro is invoked because the masterLock variable has
not been initialized. This is not seen if Tcl_CreateInterp
has been invoked because TclpInitLock is called
by TclInitSubsystems.

However, the Tcl_RegExpCompile, for example is
supposed to be callable with the Tcl_Interp parameter
set to NULL (0).

In the unix implementation, the corresponding variable
is initialized at compile time through a static initializer
static pthread_mutex_t masterLock =
PTHREAD_MUTEX_INITIALIZER;
this cannot be done on windows because a call
to InitializeCriticalSection is required.

One possible fix is change the macro for MASTER_LOCK
to call the TclpMasterLock function in tclWinThrd.c
This seems reasonable and it only affects this one file.

In the meantime, it appears that a call to Tcl_GetTime
will initialize the masterLock mutex.

Discussion

  • Andreas Kupries

    Andreas Kupries - 2004-07-09

    Logged In: YES
    user_id=75003

    Given to Zoran, he knows thread stuff better. Reprioritizing
    because of the possible seg.fault.

     
  • Andreas Kupries

    Andreas Kupries - 2004-07-09
    • priority: 5 --> 8
    • assigned_to: andreas_kupries --> vasiljevic
     
  • Don Porter

    Don Porter - 2004-07-09

    Logged In: YES
    user_id=80530

    I believe this is just failure to
    call Tcl_FindExecutable()
    in a slightly different variation
    from the usual.

    Add a Tcl_FindExecutable(NULL)
    to your program before any other
    calls into the Tcl library and see if that
    corrects the problem.

     
  • Zoran Vasiljevic

    Logged In: YES
    user_id=95086

    Yes. This is the probable cause. The fact is that we should be
    really exposing a kind of Tcl_Initialize() call just to be symetric
    to Tcl_Finalize(). This way people would have a clear idea
    what to do when using the library services w/o actually
    creating an interp. I do not know if this one needs a TIP.
    I believe not.

     
  • Jeffrey Sorensen

    Logged In: YES
    user_id=1080292

    I concur with the comments and think that it would be a good
    thing to have an initialize function, although most of Tcl's
    code currently checks and performs initialization of static
    data through local test and set routines.

    On the other hand, the change I'm suggesting would make the
    windows code more like the unix code (which doesn't have
    this problem); would solve the immediate problem of using
    Tcl as a library without creating an interpreter (on
    windows); would not result in significant overhead; and
    finally, would only change this local file locally at
    compile time. I cannot conceive of an argument against
    making this change.

    Specifically, the change is this
    > #define MASTER_LOCK EnterCriticalSection(&masterLock)
    > #define MASTER_UNLOCK LeaveCriticalSection(&masterLock)
    would become
    < #define MASTER_LOCK TclpMasterLock()
    < #define MASTER_UNLOCK TclpMasterUnlock()

    While I concur with dgp that there are many Tcl functions
    that could be called, perhaps most obviously
    Tcl_CreateInterp, that would perform this initialization,
    the documentation does not suggest that this should be
    required. In fact, on unix, it does not seem to be required
    at all. Perhaps this is not true if you call some deep Tcl
    functions. The most likely library calls to be used in this
    fashion are Tcl_Obj manipulation, string handling esp.
    utf-8, and regular expressions.

     
  • Zoran Vasiljevic

    Logged In: YES
    user_id=95086

    Whats wrong with
    void Tcl_Initialize(void)
    {
    TclInitSubsystems(NULL);
    }

    This takes care about all subsystems in Tcl. After this call
    everything including the object system, notifier thread,
    encoding system etc etc are properly setup w/o need to
    call Tcl_CreateInterp or Tcl_FindExecutable. This would
    benefit the Tcl API better in terms of symetry.

    Besides, there is nothing wrong with your proposal

    > #define MASTER_LOCK EnterCriticalSection(&masterLock)
    > #define MASTER_UNLOCK LeaveCriticalSection(&masterLock)
    would become
    < #define MASTER_LOCK TclpMasterLock()
    < #define MASTER_UNLOCK TclpMasterUnlock()

    This seems ok on the first glance.

     
  • Don Porter

    Don Porter - 2004-07-11

    Logged In: YES
    user_id=80530

    All sounds fine to me. I'd say
    the MASTER_LOCK changes could
    go in for both 8.4.7 and 8.5. That
    would solve the immediate issue, right?

    A Tcl_Initialize() routine also sounds
    promising, but will need a TIP.

    See also Patch 9876520 for other work
    in progress on reforming Tcl's startup
    sequence.

     
  • Zoran Vasiljevic

    • status: open --> closed-accepted
     
  • Zoran Vasiljevic

    Logged In: YES
    user_id=95086

    Applied to both core-8-4-branch and head.
    Jeffrey, can you please checkout and try this on Win?
    Thanks.

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2004-07-19

    Logged In: YES
    user_id=72656

    Passes all tests for core-8-4-branch Win XP VC++ 6 build
    with --enable-threads --enable-symbols=all.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks