Tcl Source Code

Check-in [ab427ec84e]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:* generic/tclInt.h: * generic/tclLoad.c (TclFinalizeLoad): * generic/tclEvent.c (Tcl_Finalize): Defer unloading of loadable modules until all exit handlers have been invoked. [Bug: 998, 1273, 1573, 1593]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-1-branch-old
Files: files | file ages | folders
SHA1:ab427ec84e6d7f6b43d4cf028ec409e0bdf005ad
User & Date: stanton 1999-03-30 22:29:02
Context
1999-03-30
22:29
*** empty log message *** check-in: 88e6d9a8d3 user: stanton tags: core-8-1-branch-old
22:29
* generic/tclInt.h: * generic/tclLoad.c (TclFinalizeLoad): * generic/tclEvent.c (Tcl_Finalize): Defe... check-in: ab427ec84e user: stanton tags: core-8-1-branch-old
04:14
updated GB encoding to be multibyte check-in: bf94a29051 user: stanton tags: core-8-1-branch-old
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclEvent.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
852
853
854
855
856
857
858







859
860
861
862
863
864
865
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclEvent.c,v 1.1.2.8 1999/03/13 03:09:33 surles Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The data structure below is used to report background errors.  One
................................................................................
	 * In particular, the testexithandler command sets up something
	 * that writes to standard output, which gets closed.
	 * Note that there is no thread-local storage after this call.
	 */
    
	Tcl_FinalizeThread();








	/*
	 * Now finalize the Tcl execution environment.  Note that this
	 * must be done after the exit handlers, because there are
	 * order dependencies.
	 */

	TclFinalizeCompExecEnv();






|







 







>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclEvent.c,v 1.1.2.9 1999/03/30 22:29:02 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The data structure below is used to report background errors.  One
................................................................................
	 * In particular, the testexithandler command sets up something
	 * that writes to standard output, which gets closed.
	 * Note that there is no thread-local storage after this call.
	 */
    
	Tcl_FinalizeThread();

	/*
	 * We defer unloading of packages until after any user callbacks
	 * are invoked to avoid memory access issues.
	 */

	TclFinalizeLoad();

	/*
	 * Now finalize the Tcl execution environment.  Note that this
	 * must be done after the exit handlers, because there are
	 * order dependencies.
	 */

	TclFinalizeCompExecEnv();

Changes to generic/tclInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1791
1792
1793
1794
1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
 * Copyright (c) 1993-1997 Lucent Technologies.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * 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.1.2.15 1999/03/24 04:25:14 stanton Exp $
 */

#ifndef _TCLINT
#define _TCLINT

/*
 * Common include files needed by most of the Tcl source files are
................................................................................
EXTERN void		TclFinalizeCondition _ANSI_ARGS_((
			    Tcl_Condition *condPtr));
EXTERN void		TclFinalizeCompilation _ANSI_ARGS_((void));
EXTERN void		TclFinalizeEncodingSubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeEnvironment _ANSI_ARGS_((void));
EXTERN void		TclFinalizeExecution _ANSI_ARGS_((void));
EXTERN void		TclFinalizeIOSubsystem _ANSI_ARGS_((void));

EXTERN void		TclFinalizeMemorySubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeMutex _ANSI_ARGS_((Tcl_Mutex *mutex));
EXTERN void		TclFinalizeNotifier _ANSI_ARGS_((void));
EXTERN void		TclFinalizeSynchronization _ANSI_ARGS_((void));
EXTERN void		TclFinalizeThreadData _ANSI_ARGS_((void));
EXTERN void		TclFindEncodings _ANSI_ARGS_((CONST char *argv0));
EXTERN Proc *		TclFindProc _ANSI_ARGS_((Interp *iPtr,






|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
 * Copyright (c) 1993-1997 Lucent Technologies.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * 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.1.2.16 1999/03/30 22:29:03 stanton Exp $
 */

#ifndef _TCLINT
#define _TCLINT

/*
 * Common include files needed by most of the Tcl source files are
................................................................................
EXTERN void		TclFinalizeCondition _ANSI_ARGS_((
			    Tcl_Condition *condPtr));
EXTERN void		TclFinalizeCompilation _ANSI_ARGS_((void));
EXTERN void		TclFinalizeEncodingSubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeEnvironment _ANSI_ARGS_((void));
EXTERN void		TclFinalizeExecution _ANSI_ARGS_((void));
EXTERN void		TclFinalizeIOSubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeLoad _ANSI_ARGS_((void));
EXTERN void		TclFinalizeMemorySubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeMutex _ANSI_ARGS_((Tcl_Mutex *mutex));
EXTERN void		TclFinalizeNotifier _ANSI_ARGS_((void));
EXTERN void		TclFinalizeSynchronization _ANSI_ARGS_((void));
EXTERN void		TclFinalizeThreadData _ANSI_ARGS_((void));
EXTERN void		TclFindEncodings _ANSI_ARGS_((CONST char *argv0));
EXTERN Proc *		TclFindProc _ANSI_ARGS_((Interp *iPtr,

Changes to generic/tclLoad.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
...
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
 *	on all platforms) of Tcl's dynamic loading facilities.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclLoad.c,v 1.1.2.3 1998/12/10 21:21:49 stanton Exp $
 */

#include "tclInt.h"

/*
 * The following structure describes a package that has been loaded
 * either dynamically (with the "load" command) or statically (as
................................................................................

/*
 * Prototypes for procedures that are private to this file:
 */

static void		LoadCleanupProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
static void		LoadExitProc _ANSI_ARGS_((ClientData clientData));
 
/*
 *----------------------------------------------------------------------
 *
 * Tcl_LoadObjCmd --
 *
 *	This procedure is invoked to process the "load" Tcl command.
................................................................................
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Create a new record to describe this package.
	 */
	if (firstPackagePtr == NULL) {
	    Tcl_CreateExitHandler(LoadExitProc, (ClientData) NULL);
	}
	pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
	pkgPtr->fileName	= (char *) ckalloc((unsigned)
		(strlen(fullFileName) + 1));
	strcpy(pkgPtr->fileName, fullFileName);
	pkgPtr->packageName	= (char *) ckalloc((unsigned)
		(Tcl_DStringLength(&pkgName) + 1));
	strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));
................................................................................
	if ((pkgPtr->initProc == initProc)
		&& (pkgPtr->safeInitProc == safeInitProc)
		&& (strcmp(pkgPtr->packageName, pkgName) == 0)) {
	    Tcl_MutexUnlock(&packageMutex);
	    return;
	}
    }
    if (firstPackagePtr == NULL) {
	Tcl_CreateExitHandler(LoadExitProc, (ClientData) NULL);
    }
    Tcl_MutexUnlock(&packageMutex);

    pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
    pkgPtr->fileName		= (char *) ckalloc((unsigned) 1);
    pkgPtr->fileName[0]		= 0;
    pkgPtr->packageName		= (char *) ckalloc((unsigned)
	    (strlen(pkgName) + 1));
................................................................................
	ipPtr = nextPtr;
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * LoadExitProc --
 *
 *	This procedure is invoked just before the application exits.
 *	It frees all of the LoadedPackage structures.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

static void
LoadExitProc(clientData)
    ClientData clientData;		/* Not used. */
{
    LoadedPackage *pkgPtr;

    Tcl_MutexLock(&packageMutex);
    while (firstPackagePtr != NULL) {
	pkgPtr = firstPackagePtr;
	firstPackagePtr = pkgPtr->nextPtr;






|







 







<







 







<
<
|







 







<
<
|







 







|













|
|
<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
82
83
84
85
86
87
88

89
90
91
92
93
94
95
...
342
343
344
345
346
347
348


349
350
351
352
353
354
355
356
...
465
466
467
468
469
470
471


472
473
474
475
476
477
478
479
...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
 *	on all platforms) of Tcl's dynamic loading facilities.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclLoad.c,v 1.1.2.4 1999/03/30 22:29:03 stanton Exp $
 */

#include "tclInt.h"

/*
 * The following structure describes a package that has been loaded
 * either dynamically (with the "load" command) or statically (as
................................................................................

/*
 * Prototypes for procedures that are private to this file:
 */

static void		LoadCleanupProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));

 
/*
 *----------------------------------------------------------------------
 *
 * Tcl_LoadObjCmd --
 *
 *	This procedure is invoked to process the "load" Tcl command.
................................................................................
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Create a new record to describe this package.
	 */



	pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
	pkgPtr->fileName	= (char *) ckalloc((unsigned)
		(strlen(fullFileName) + 1));
	strcpy(pkgPtr->fileName, fullFileName);
	pkgPtr->packageName	= (char *) ckalloc((unsigned)
		(Tcl_DStringLength(&pkgName) + 1));
	strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));
................................................................................
	if ((pkgPtr->initProc == initProc)
		&& (pkgPtr->safeInitProc == safeInitProc)
		&& (strcmp(pkgPtr->packageName, pkgName) == 0)) {
	    Tcl_MutexUnlock(&packageMutex);
	    return;
	}
    }



    Tcl_MutexUnlock(&packageMutex);

    pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
    pkgPtr->fileName		= (char *) ckalloc((unsigned) 1);
    pkgPtr->fileName[0]		= 0;
    pkgPtr->packageName		= (char *) ckalloc((unsigned)
	    (strlen(pkgName) + 1));
................................................................................
	ipPtr = nextPtr;
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeLoad --
 *
 *	This procedure is invoked just before the application exits.
 *	It frees all of the LoadedPackage structures.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeLoad()

{
    LoadedPackage *pkgPtr;

    Tcl_MutexLock(&packageMutex);
    while (firstPackagePtr != NULL) {
	pkgPtr = firstPackagePtr;
	firstPackagePtr = pkgPtr->nextPtr;