Tcl Source Code

Check-in [3ddbaef356]
Login

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

Overview
Comment:OO cleanup fix that passes test 11.7.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | main
Files: files | file ages | folders
SHA3-256: 3ddbaef3566385a26d76abab4f7ebd0aa343e0d45927fbdb0f276b4d13e0ce39
User & Date: pooryorick 2021-04-02 23:02:00
Context
2021-04-03
12:33
OO cleanup fix that passes test 11.7. check-in: 40aace21eb user: pooryorick tags: core-8-branch
2021-04-02
23:21
Use TclCleanupCommandMacro instead of just decrementing the reference count. check-in: 591e2bfdd7 user: pooryorick tags: trunk, main
23:02
OO cleanup fix that passes test 11.7. check-in: 3ddbaef356 user: pooryorick tags: trunk, main
21:20
New test for OO cleanup: routine for object gets deleted before namespace deletion is complete. check-in: 330ec158a8 user: pooryorick tags: trunk, main
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclOO.c.

1180
1181
1182
1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
    /*
     * Instruct everyone to no longer use any allocated fields of the object.
     * Also delete the command that refers to the object at this point (if it
     * still exists) because otherwise its pointer to the object points into
     * freed memory.
     */


    if (((Command *) oPtr->command)->flags && CMD_DYING) {
	/*
	 * Something has already started the command deletion process. We can
	 * go ahead and clean up the the namespace,
	 */
    } else {
	/*
	 * The namespace must have been deleted directly.  Delete the command
	 * as well.
	 */

	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);

    }

    if (oPtr->myclassCommand) {
	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myclassCommand);
    }
    if (oPtr->myCommand) {
	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand);







>
|
|
<
|
|
|
|
|
|
|

|
>







1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
    /*
     * Instruct everyone to no longer use any allocated fields of the object.
     * Also delete the command that refers to the object at this point (if it
     * still exists) because otherwise its pointer to the object points into
     * freed memory.
     */

    if (oPtr->command != NULL) {
	if (((Command *) oPtr->command)->flags && CMD_DYING) {
	    /*

	     * The command is already (being) deleted. Proceed to clean up the the namespace,
	     */
	} else {
	    /*
	     * The namespace must have been deleted directly.  Delete the command
	     * as well.
	     */

	    Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
	}
    }

    if (oPtr->myclassCommand) {
	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myclassCommand);
    }
    if (oPtr->myCommand) {
	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand);

Changes to tests/oo.test.

1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786
1787
1788
1789
1790
1791
1792


test oo-11.7 {
    When an object is deleted its namespace is deleted, and all objects it is
    mixed into are also deleted.  If the object has been renamed into the
    namespace of one of the objects it has been mixed into, the routine for the
    object might get entirely deleted before the namespace of the object is
    entirely deleted, in which case the C routine the performs the namespace
    either must either understand that the handle on the routine for the object
    might now be gone, or it must be guaranteed that the handle does not
    disappear until that routine is finished.
} -setup {
} -body {
    oo::define oo::class {
	export createWithNamespace
    }
    oo::class create class1

    oo::object create obj1
    oo::objdefine obj1 {
	mixin ::class1
    }
    set obj1ns [info object namespace obj1]
    set class1ns [info object namespace class1]
    rename class1 ${obj1ns}::class1
    # No segmentation fault
    namespace delete $class1ns

} -cleanup {
    rename obj {}
} -result done


test oo-12.1 {OO: filters} {
    oo::class create Aclass
    Aclass create Aobject
    oo::define Aclass {







|
|
|
|


<
<
<











>

<







1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769



1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782

1783
1784
1785
1786
1787
1788
1789


test oo-11.7 {
    When an object is deleted its namespace is deleted, and all objects it is
    mixed into are also deleted.  If the object has been renamed into the
    namespace of one of the objects it has been mixed into, the routine for the
    object might get entirely deleted before the namespace of the object is
    entirely deleted, in which case the C routine that performs the namespace
    deletion either must either understand that the handle on the routine for
    the object might now be gone, or it must be guaranteed that the handle does
    not disappear until that routine is finished.
} -setup {
} -body {



    oo::class create class1

    oo::object create obj1
    oo::objdefine obj1 {
	mixin ::class1
    }
    set obj1ns [info object namespace obj1]
    set class1ns [info object namespace class1]
    rename class1 ${obj1ns}::class1
    # No segmentation fault
    namespace delete $class1ns
    return done
} -cleanup {

} -result done


test oo-12.1 {OO: filters} {
    oo::class create Aclass
    Aclass create Aobject
    oo::define Aclass {