diff options
author | dgp <dgp@users.sourceforge.net> | 2004-11-30 19:34:44 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2004-11-30 19:34:44 (GMT) |
commit | 999c1d1867082cb366aeb7bb7d6f46f27ed40596 (patch) | |
tree | 3f6ea55c8096d98ba728284819430a49be305cf6 /generic/tclInt.h | |
parent | f1608d9d16479048838c99d496b9f2812de574f2 (diff) | |
download | tcl-999c1d1867082cb366aeb7bb7d6f46f27ed40596.zip tcl-999c1d1867082cb366aeb7bb7d6f46f27ed40596.tar.gz tcl-999c1d1867082cb366aeb7bb7d6f46f27ed40596.tar.bz2 |
Patch 976520 reworks several of the details involved with
startup/initialization of the Tcl library, focused on the
activities of Tcl_FindExecutable().
* generic/tclIO.c: Removed bogus claim in comment that
encoding "iso8859-1" is "built-in" to Tcl.
* generic/tclInt.h: Created a new struct ProcessGlobalValue,
* generic/tclUtil.c: routines Tcl(Get|Set)ProcessGlobalValue,
and function type TclInitProcessGlobalValueProc. Together, these
take care of the housekeeping for "values" (things that can be
held in a Tcl_Obj) that are global across a whole process. That is,
they are shared among multiple threads, and epoch and mutex
protection must govern the validity of cached copies maintained
in each thread.
* generic/tclNotify.c: Modified TclInitNotifier() to tolerate
being called multiple times in the same thread.
* generic/tclEvent.c: Dropped the unused argv0 argument to
TclInitSubsystems(). Removed machinery to unsure only one
TclInitNotifier() call per thread, now that that is safe.
Converted Tcl(Get|Set)LibraryPath to use a ProcessGlobalValue,
and moved them to tclEncoding.c.
* generic/tclBasic.c: Updated caller.
* generic/tclInt.h: TclpFindExecutable now returns void.
* unix/tclUnixFile.c:
* win/tclWinFile.c:
* win/tclWinPipe.c:
* generic/tclEncoding.c: Built new encoding search initialization
on a foundation of ProcessGlobalValues, exposing new routines
Tcl(Get|Set)EncodingSearchPath. A cache of a map from encoding name
to directory pathname keeps track of where encodings are available
for loading. Tcl_FindExecutable greatly simplified into just
three function calls. The "library path" is now misnamed, as its
only remaining purpose is as a foundation for the default encoding
search path.
* generic/tclInterp.c: Inlined the initScript that is evaluated
by Tcl_Init(). Added verification after initScript evaluation
that Tcl can find its installed *.enc files, and that it has
initialized [encoding system] in agreement with what the environment
expects. [tclInit] no longer driven by the value of $::tcl_libPath;
it largely constructs its own search path now, rather than attempt
to share one with the encoding system.
* unix/tclUnixInit.c: TclpSetInitialEncodings factored so that a new
* win/tclWinInit.c: routine TclpGetEncodingNameFromEnvironment
can reveal that Tcl thinks the [encoding system] should be, even
when an incomplete encoding search path, or a missing *.enc file
won't allow that initialization to succeed. TclpInitLibraryPath
reworked as an initializer of a ProcessGlobalValue.
* unix/tclUnixTest.c: Update implementations of [testfindexecutable],
[testgetdefenc], and [testsetdefenc].
* tests/unixInit.test: Corrected tests to operate properly even
when a value of TCL_LIBRARY is required to find encodings.
* generic/tclInt.decls: New internal stubs: TclGetEncodingSearchPath,
TclSetEncodingSearchPath, TclpGetEncodingNameFromEnvironment. These
are candidates for public exposure by future TIPs.
* generic/tclIntDecls.h: make genstubs
* generic/tclStubInit.c:
* generic/tclTest.c: Updated [testencoding] to use
* tests/encoding.test: Tcl(Get|Set)EncodingSearchPath. Updated tests.
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r-- | generic/tclInt.h | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h index a4ac12e..4510239 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclInt.h,v 1.200 2004/11/17 17:53:01 dgp Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.201 2004/11/30 19:34:48 dgp Exp $ */ #ifndef _TCLINT @@ -1688,14 +1688,46 @@ typedef Tcl_ObjCmdProc *TclObjCmdProcType; /* *---------------------------------------------------------------- + * Data structures for process-global values. + *---------------------------------------------------------------- + */ + +typedef void (TclInitProcessGlobalValueProc) _ANSI_ARGS_((char **valuePtr, + int *lengthPtr, Tcl_Encoding *encodingPtr)); + +/* + * A ProcessGlobalValue struct exists for each internal value in + * Tcl that is to be shared among several threads. Each thread + * sees a (Tcl_Obj) copy of the value, and the master is kept as + * a counted string, with epoch and mutex control. Each ProcessGlobalValue + * struct should be a static variable in some file. + */ +typedef struct ProcessGlobalValue { + int epoch; /* Epoch counter to detect changes + * in the master value */ + int numBytes; /* Length of the master string */ + char *value; /* The master string value */ + Tcl_Encoding encoding; /* system encoding when master string + * was initialized */ + TclInitProcessGlobalValueProc *proc; + /* A procedure to initialize the + * master string copy when a "get" + * request comes in before any + * "set" request has been received. */ + Tcl_Mutex mutex; /* Enforce orderly access from + * multiple threads */ + Tcl_ThreadDataKey key; /* Key for per-thread data holding + * the (Tcl_Obj) copy for each thread */ +} ProcessGlobalValue; + +/* + *---------------------------------------------------------------- * Variables shared among Tcl modules but not used by the outside world. *---------------------------------------------------------------- */ -MODULE_SCOPE char * tclExecutableName; MODULE_SCOPE char * tclNativeExecutableName; MODULE_SCOPE int tclFindExecutableSearchDone; -MODULE_SCOPE char * tclDefaultEncodingDir; MODULE_SCOPE char * tclMemDumpFileName; MODULE_SCOPE TclPlatformType tclPlatform; MODULE_SCOPE Tcl_NotifierProcs tclOriginalNotifier; @@ -1802,6 +1834,8 @@ MODULE_SCOPE void TclFinalizeSynchronization _ANSI_ARGS_((void)); MODULE_SCOPE void TclFinalizeLock _ANSI_ARGS_((void)); MODULE_SCOPE void TclFinalizeThreadData _ANSI_ARGS_((void)); MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler _ANSI_ARGS_((Tcl_Interp *interp)); +MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue _ANSI_ARGS_ (( + ProcessGlobalValue *pgvPtr)); MODULE_SCOPE int TclGlob _ANSI_ARGS_((Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData* types)); @@ -1815,7 +1849,7 @@ MODULE_SCOPE void TclInitLimitSupport _ANSI_ARGS_((Tcl_Interp *interp)); MODULE_SCOPE void TclInitNamespaceSubsystem _ANSI_ARGS_((void)); MODULE_SCOPE void TclInitNotifier _ANSI_ARGS_((void)); MODULE_SCOPE void TclInitObjSubsystem _ANSI_ARGS_((void)); -MODULE_SCOPE void TclInitSubsystems _ANSI_ARGS_((CONST char *argv0)); +MODULE_SCOPE void TclInitSubsystems (); MODULE_SCOPE int TclIsLocalScalar _ANSI_ARGS_((CONST char *src, int len)); MODULE_SCOPE int TclJoinThread _ANSI_ARGS_((Tcl_ThreadId id, @@ -1879,11 +1913,12 @@ MODULE_SCOPE int TclpThreadCreate _ANSI_ARGS_(( int stackSize, int flags)); MODULE_SCOPE void TclpFinalizeThreadDataKey _ANSI_ARGS_(( Tcl_ThreadDataKey *keyPtr)); -MODULE_SCOPE char * TclpFindExecutable _ANSI_ARGS_(( +MODULE_SCOPE void TclpFindExecutable _ANSI_ARGS_(( CONST char *argv0)); MODULE_SCOPE int TclpFindVariable _ANSI_ARGS_((CONST char *name, int *lengthPtr)); -MODULE_SCOPE int TclpInitLibraryPath _ANSI_ARGS_((CONST char *argv0)); +MODULE_SCOPE void TclpInitLibraryPath _ANSI_ARGS_((char **valuePtr, + int *lengthPtr, Tcl_Encoding *encodingPtr)); MODULE_SCOPE void TclpInitLock _ANSI_ARGS_((void)); MODULE_SCOPE void TclpInitPlatform _ANSI_ARGS_((void)); MODULE_SCOPE void TclpInitUnlock _ANSI_ARGS_((void)); @@ -1951,6 +1986,8 @@ MODULE_SCOPE void TclRemoveScriptLimitCallbacks _ANSI_ARGS_(( Tcl_Interp *interp)); MODULE_SCOPE void TclSetBgErrorHandler _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *cmdPrefix)); +MODULE_SCOPE void TclSetProcessGlobalValue _ANSI_ARGS_ (( + ProcessGlobalValue *pgvPtr, Tcl_Obj *newValue)); MODULE_SCOPE VOID TclSignalExitThread _ANSI_ARGS_((Tcl_ThreadId id, int result)); MODULE_SCOPE int TclSubstTokens _ANSI_ARGS_((Tcl_Interp *interp, |