Index: TODO =================================================================== diff -u -re52f2dd0f35e8a12230a20e90575f242da4e0e5c -r7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8 --- TODO (.../TODO) (revision e52f2dd0f35e8a12230a20e90575f242da4e0e5c) +++ TODO (.../TODO) (revision 7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8) @@ -3570,6 +3570,11 @@ - experimentation version of unknown handler for non-pos args - extending regression test +nsf.c: + - moved methodEpochCounters from global vars to the interp state + to improve resue in multi threaded apps + - separated objectMethodEpoch and instanceMethodEpoch + - bumped version number to 2.0a2 TODO: Index: configure =================================================================== diff -u -rb37bf2deab94b6294509fa79bb7b922d6e8a5635 -r7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8 --- configure (.../configure) (revision b37bf2deab94b6294509fa79bb7b922d6e8a5635) +++ configure (.../configure) (revision 7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8) @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for nsf 2.0a1. +# Generated by GNU Autoconf 2.68 for nsf 2.0a2. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -557,8 +557,8 @@ # Identity of this package. PACKAGE_NAME='nsf' PACKAGE_TARNAME='nsf' -PACKAGE_VERSION='2.0a1' -PACKAGE_STRING='nsf 2.0a1' +PACKAGE_VERSION='2.0a2' +PACKAGE_STRING='nsf 2.0a2' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1305,7 +1305,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures nsf 2.0a1 to adapt to many kinds of systems. +\`configure' configures nsf 2.0a2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1366,7 +1366,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of nsf 2.0a1:";; + short | recursive ) echo "Configuration of nsf 2.0a2:";; esac cat <<\_ACEOF @@ -1486,7 +1486,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -nsf configure 2.0a1 +nsf configure 2.0a2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1851,7 +1851,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by nsf $as_me 2.0a1, which was +It was created by nsf $as_me 2.0a2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -9103,7 +9103,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by nsf $as_me 2.0a1, which was +This file was extended by nsf $as_me 2.0a2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -9156,7 +9156,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -nsf config.status 2.0a1 +nsf config.status 2.0a2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Index: configure.in =================================================================== diff -u -rb37bf2deab94b6294509fa79bb7b922d6e8a5635 -r7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8 --- configure.in (.../configure.in) (revision b37bf2deab94b6294509fa79bb7b922d6e8a5635) +++ configure.in (.../configure.in) (revision 7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8) @@ -11,7 +11,7 @@ # for this package, and can be a relative path, such as: # #-------------------------------------------------------------------- -define(NsfVersion, 2.0a1) +define(NsfVersion, 2.0a2) AC_INIT([nsf], [NsfVersion]) #-------------------------------------------------------------------- Index: generic/nsf.c =================================================================== diff -u -r5d459faf89b80af6b137c2a32dad0fd9d0a4cd74 -r7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8 --- generic/nsf.c (.../nsf.c) (revision 5d459faf89b80af6b137c2a32dad0fd9d0a4cd74) +++ generic/nsf.c (.../nsf.c) (revision 7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8) @@ -163,13 +163,19 @@ } enumeratorConverterEntry; static enumeratorConverterEntry enumeratorConverterEntries[]; -static int nsfMethodEpoch = 0; +/* + * Definition of methodEpoch macros + */ #if defined(METHOD_OBJECT_TRACE) -# define NsfMethodEpochIncr(msg) \ - nsfMethodEpoch++; \ - fprintf(stderr, "+++ methodEpoch %d %s\n", nsfMethodEpoch, msg); +# define NsfInstanceMethodEpochIncr(msg) \ + RUNTIME_STATE(interp)->instanceMethodEpoch++; \ + fprintf(stderr, "+++ instanceMethodEpoch %d %s\n", RUNTIME_STATE(interp)->instanceMethodEpoch, msg) +# define NsfObjectMethodEpochIncr(msg) \ + RUNTIME_STATE(interp)->objectMethodEpoch++; \ + fprintf(stderr, "+++ objectMethodEpoch %d %s\n", RUNTIME_STATE(interp)->objectMethodEpoch, msg) #else -# define NsfMethodEpochIncr(msg) nsfMethodEpoch++ +# define NsfInstanceMethodEpochIncr(msg) RUNTIME_STATE(interp)->instanceMethodEpoch++ +# define NsfObjectMethodEpochIncr(msg) RUNTIME_STATE(interp)->objectMethodEpoch++ #endif /* @@ -919,7 +925,7 @@ NsfRemoveObjectMethod(Tcl_Interp *interp, Nsf_Object *object1, CONST char *methodName) { NsfObject *object = (NsfObject *) object1; - NsfMethodEpochIncr("NsfRemoveObjectMethod"); + NsfObjectMethodEpochIncr("NsfRemoveObjectMethod"); AliasDelete(interp, object->cmdName, methodName, 1); @@ -946,7 +952,7 @@ NsfClassOpt *opt = cl->opt; #endif - NsfMethodEpochIncr("NsfRemoveClassMethod"); + NsfInstanceMethodEpochIncr("NsfRemoveClassMethod"); AliasDelete(interp, class->object.cmdName, methodName, 0); @@ -9139,7 +9145,11 @@ methodName, cmd, cscPtr);*/ assert(cscPtr->cmdPtr == cmd); Tcl_DeleteCommandFromToken(interp, cmd); - NsfMethodEpochIncr("DeleteObjectAlias"); + if (cscPtr->cl) { + NsfInstanceMethodEpochIncr("DeleteObjectAlias"); + } else { + NsfObjectMethodEpochIncr("DeleteObjectAlias"); + } NsfCleanupObject(invokeObj, "alias-delete1"); return NsfPrintError(interp, "Trying to dispatch deleted object via method '%s'", @@ -9515,6 +9525,7 @@ int validCscPtr = 1; // TODO: best place? //NsfCallStackContent *cscPtr1 = CallStackGetTopFrame0(interp); + NsfRuntimeState *rst = RUNTIME_STATE(interp); /* none of the higher copy-flags must be passed */ assert((flags & (NSF_CSC_COPY_FLAGS & 0xFFF000)) == 0); @@ -9581,7 +9592,6 @@ assert((flags & (NSF_CSC_MIXIN_STACK_PUSHED|NSF_CSC_FILTER_STACK_PUSHED)) == 0); if (((objflags & NSF_FILTER_ORDER_DEFINED_AND_VALID) == NSF_FILTER_ORDER_DEFINED_AND_VALID)) { - NsfRuntimeState *rst = RUNTIME_STATE(interp); if (rst->doFilters && !rst->guardCount) { NsfCallStackContent *cscPtr1 = CallStackGetTopFrame0(interp); @@ -9729,10 +9739,11 @@ if (likely(cmd == NULL)) { NsfMethodContext *mcPtr = methodObj->internalRep.twoPtrValue.ptr1; + int nsfObjectMethodEpoch = rst->objectMethodEpoch; if (methodObj->typePtr == &NsfObjectMethodObjType && mcPtr->context == object - && mcPtr->methodEpoch == nsfMethodEpoch + && mcPtr->methodEpoch == nsfObjectMethodEpoch && mcPtr->flags == flags ) { cmd = mcPtr->cmd; @@ -9754,7 +9765,7 @@ cmd = NULL; } else { NsfMethodObjSet(interp, methodObj, &NsfObjectMethodObjType, - object, nsfMethodEpoch, + object, nsfObjectMethodEpoch, cmd, NULL, flags); } } @@ -9772,19 +9783,20 @@ /* check for a method inherited from a class */ NsfClass *currentClass = object->cl; NsfMethodContext *mcPtr = methodObj->internalRep.twoPtrValue.ptr1; + int nsfInstanceMethodEpoch = rst->instanceMethodEpoch; #if defined(METHOD_OBJECT_TRACE) fprintf(stderr, "... method %p '%s' type? %d context? %d nsfMethodEpoch %d/%d\n", methodObj, ObjStr(methodObj), methodObj->typePtr == &NsfInstanceMethodObjType, methodObj->typePtr == &NsfInstanceMethodObjType ? currentClass : 0, methodObj->typePtr == &NsfInstanceMethodObjType ? mcPtr->methodEpoch : 0, - nsfMethodEpoch ); + nsfInstanceMethodEpoch ); #endif if (methodObj->typePtr == &NsfInstanceMethodObjType && mcPtr->context == currentClass - && mcPtr->methodEpoch == nsfMethodEpoch + && mcPtr->methodEpoch == nsfInstanceMethodEpoch && mcPtr->flags == flags ) { cmd = mcPtr->cmd; @@ -9813,7 +9825,7 @@ } NsfMethodObjSet(interp, methodObj, &NsfInstanceMethodObjType, - currentClass, nsfMethodEpoch, + currentClass, nsfInstanceMethodEpoch, cmd, cl, flags); } } @@ -11652,11 +11664,12 @@ #endif } - NsfMethodEpochIncr("MakeMethod"); if (cl) { + NsfInstanceMethodEpochIncr("MakeMethod"); /* could be a filter or filter inheritance ... update filter orders */ FilterInvalidateObjOrders(interp, cl); } else { + NsfObjectMethodEpochIncr("MakeMethod"); /* could be a filter => recompute filter order */ FilterComputeDefined(interp, defObject); } @@ -13324,9 +13337,6 @@ } /* - * bring an object into a state, as after initialization - */ -/* *---------------------------------------------------------------------- * CleanupDestroyObject -- * @@ -13346,8 +13356,9 @@ /*fprintf(stderr, "CleanupDestroyObject obj %p softrecreate %d nsPtr %p\n", object, softrecreate, object->nsPtr);*/ - NsfMethodEpochIncr("CleanupDestroyObject"); + //NsfObjectMethodEpochIncr("CleanupDestroyObject"); + /* remove the instance, but not for ::Class/::Object */ if ((object->flags & NSF_IS_ROOT_CLASS) == 0 && (object->flags & NSF_IS_ROOT_META_CLASS) == 0 ) { @@ -14122,7 +14133,7 @@ ChangeClass(Tcl_Interp *interp, NsfObject *object, NsfClass *cl) { assert(object); - NsfMethodEpochIncr("ChangeClass"); + NsfInstanceMethodEpochIncr("ChangeClass"); /*fprintf(stderr, "changing %s to class %s ismeta %d\n", ObjectName(object), ClassName(cl), Index: generic/nsfInt.h =================================================================== diff -u -re52f2dd0f35e8a12230a20e90575f242da4e0e5c -r7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8 --- generic/nsfInt.h (.../nsfInt.h) (revision e52f2dd0f35e8a12230a20e90575f242da4e0e5c) +++ generic/nsfInt.h (.../nsfInt.h) (revision 7d1e68dd44eb6cddb6755e335e1070bb7be2e6f8) @@ -383,6 +383,7 @@ #define NSF_RECREATE 0x8000 + /* flags for NsfParams */ #define NSF_ARG_REQUIRED 0x000001 @@ -762,6 +763,8 @@ Tcl_Command colonCmd; /* cmdPtr of cmd ":" to dispatch via cmdResolver */ Proc fakeProc; /* dummy proc strucure, used for C-implemented methods with local scope */ Tcl_Command currentMixinCmdPtr; /* cmdPtr of currently active mixin, used for "info activemixin" */ + int objectMethodEpoch; + int instanceMethodEpoch; Tcl_Obj **methodObjNames; /* global objects of nsf */ struct NsfShadowTclCommandInfo *tclCommands; /* shadowed Tcl commands */