From: federico@heinz.in-berlin.de (Federico Heinz)
Subject: Using NX_DURING and friends in multiple threads
Keywords: NX_DURING exception handling multi-thread
Organization: Federico Heinz Consulting
Date: Sat, 15 Aug 1992 10:26:36 GMT

Folks,

I have discovered---the hard way---that the exception-handling  
mechanism (NX_DURING / NX_HANDLER / NX_ENDHANDLER) is not  
thread-safe, that is, no two threads may use this mechanism  
concurrently. Aside from race conditions, as far as I can tell  
there is only one global exception handler chain. Thus, if you have  
more than one thread  setting exception handling domains  
constructs, this chain will contain the handlers for both threads,  
royally screwing up everything: an exception raised in thread A may  
very well be catched by a handler in thread B, which makes no sense  
whatsoever.

I have reimplemented the exception handling runtime support to make  
it safely useable by an arbitrary number of threads. The key  
routines for doing this are _NXAddHandler(), _NXRemoveHandler() and  
_NXRaiseError(), and the implementation is rather easy. The problem  
is plugging this support in place: first I thought of naming the  
routines just like NeXT's counterparts (_NXAddHandler(), etc) and  
link the resulting object file before NeXT's libraries. This would  
have been the clean solution, but it was prevented by the fact that  
NeXT's code is in the shared library, and we cannot supersede a  
module that is in the shared library (the linker barks).

Time for the messy solution: name the routines with another prefix  
(FH instead of NX), and either redefine NX_DURING and friends to  
call my routines, or define new macros FH_DURING et cetera that  
call them. Both approaches work for my source files, but there's  
still the problem that NeXT's libraries also contain numerous  
places at which exception handling domains are set up, and there's  
no way that changing a macro will modify the behavior of an already  
compiled module: they call _NXAddHandler(), there's no changing it,  
and it leads to disaster (we then have *too many* exception chains  
instead of
too few).

It's easy to redirect calls to _NXRaiseError() to my  
_FHRaiseError(), since there's a published way to do it, but I need  
to do it for _NXAddHandler() and _NXRemoveHandler() too, and I  
can't think of a way to do it. My question is simple: am I trying  
the impossible?  (which would mean it's time for the mega-messy  
solution, but I'd like to avoid it if I could). Does anybody know  
what the undocumented symbols _NXAddAltHandler and  
_NXRemoveAltHandler in except.o inside libsys are for?

	Federico



-- NewsGrazer, a NeXTstep(tm) news reader, posting --
M>UQR=&8P7&%N<VE[7&9O;G1T8FQ<9C!<9FUO9&5R;B!#;W5R:65R.WT*7&UA
M<F=L,3(P"EQM87)G<C$R,`I[7&-O;&]R=&)L7')E9#!<9W)E96XP7&)L=64P
M.WT*7'!A<F1<='@Q,S0T7'1X,C8X.%QT>#0P,S)<='@U,S<V7'1X-C<R,%QT
M>#@P-C1<='@Y-#`X7'1X,3`W-3)<='@Q,C`Y-EQT>#$S-#0P7&8P7&(P7&DP
M7'5L,%QF<S(X7&9C,"!&;VQK<RQ<"EP*22!H879E(&1I<V-O=F5R960M+2UT
M:&4@:&%R9"!W87DM+2UT:&%T('1H92!E>&-E<'1I;VXM:&%N9&QI;F<@;65C
M:&%N:7-M("A.6%]$55))3D<@+R!.6%](04Y$3$52("\@3EA?14Y$2$%.1$Q%
M4BD@:7,@;F]T('1H<F5A9"US869E+"!T:&%T(&ES+"!N;R!T=V\@=&AR96%D
M<R!M87D@=7-E('1H:7,@;65C:&%N:7-M(&-O;F-U<G)E;G1L>2X@07-I9&4@
M9G)O;2!R86-E(&-O;F1I=&EO;G,L(&%S(&9A<B!A<R!)(&-A;B!T96QL('1H
M97)E(&ES(&]N;'D@;VYE(&=L;V)A;"!E>&-E<'1I;VX@:&%N9&QE<B!C:&%I
M;BX@5&AU<RP@:68@>6]U(&AA=F4@;6]R92!T:&%N(&]N92!T:')E860@('-E
M='1I;F<@97AC97!T:6]N(&AA;F1L:6YG(&1O;6%I;G,@8V]N<W1R=6-T<RP@
M=&AI<R!C:&%I;B!W:6QL(&-O;G1A:6X@=&AE(&AA;F1L97)S(&9O<B!B;W1H
M('1H<F5A9',L(')O>6%L;'D@<V-R97=I;F<@=7`@979E<GET:&EN9SH@86X@
M97AC97!T:6]N(')A:7-E9"!I;B!T:')E860@02!M87D@=F5R>2!W96QL(&)E
M(&-A=&-H960@8GD@82!H86YD;&5R(&EN('1H<F5A9"!"+"!W:&EC:"!M86ME
M<R!N;R!S96YS92!W:&%T<V]E=F5R+EP*7`H*22!H879E(')E:6UP;&5M96YT
M960@=&AE(&5X8V5P=&EO;B!H86YD;&EN9R!R=6YT:6UE('-U<'!O<G0@=&\@
M;6%K92!I="!S869E;'D@"G5S96%B;&4@8GD@86X@87)B:71R87)Y(&YU;6)E
M<B!O9B!T:')E861S+B!4:&4@:V5Y(')O=71I;F5S(&9O<B!D;VEN9R!T:&ES
M(&%R92!?3EA!9&1(86YD;&5R*"DL(%].6%)E;6]V94AA;F1L97(H*2!A;F0@
M7TY84F%I<V5%<G)O<B@I+"!A;F0@=&AE(&EM<&QE;65N=&%T:6]N(&ES(')A
M=&AE<B!E87-Y+@H@5&AE('!R;V)L96T@:7,@<&QU9V=I;F<@=&AI<R!S=7!P
M;W)T(&EN('!L86-E.B!F:7)S="!)('1H;W5G:'0@;V8@;F%M:6YG('1H92!R
M;W5T:6YE<R!J=7-T(&QI:V4@3F585"=S(&-O=6YT97)P87)T<R`H7TY8061D
M2&%N9&QE<B@I"BP@971C*2!A;F0@;&EN:R!T:&4@<F5S=6QT:6YG(&]B:F5C
M="!F:6QE(&)E9F]R92!.95A4)W,@;&EB<F%R:65S+B!4:&ES('=O=6QD(&AA
M=F4@8F5E;B!T:&4@8VQE86X@<V]L=71I;VXL(&)U="!I="!W87,@<')E=F5N
M=&5D(&)Y('1H92!F86-T('1H870@3F585"=S(&-O9&4@:7,@:6X@=&AE('-H
M87)E9"!L:6)R87)Y+"!A;F0@=V4*(&-A;FYO="!S=7!E<G-E9&4@82!M;V1U
M;&4@=&AA="!I<R!I;B!T:&4@<VAA<F5D(&QI8G)A<GD@*'1H92!L:6YK97(@
M8F%R:W,I+EP*7`H*5&EM92!F;W(@=&AE(&UE<W-Y('-O;'5T:6]N.B!N86UE
M('1H92!R;W5T:6YE<R!W:71H(&%N;W1H97(@<')E9FEX("A&2"!I;G-T96%D
M(&]F($Y8*2P@86YD(&5I=&AE<B!R961E9FEN92!.6%]$55))3D<@86YD(&9R
M:65N9',@=&\@8V%L;"!M>2!R;W5T:6YE<RP@;W(@9&5F:6YE(&YE=R!M86-R
M;W,@1DA?1%5224Y'(&5T(&-E=&5R82!T:&%T(&-A;&P@=&AE;2X@0F]T:"!A
M<'!R;V%C:&5S('=O<FL@9F]R(&UY('-O=7)C92!F:6QE<RP@8G5T('1H97)E
M)W,@<W1I;&P@=&AE('!R;V)L96T@=&AA=`H@3F585"=S(&QI8G)A<FEE<R!A
M;'-O"B!C;VYT86EN"B!N=6UE<F]U<R!P;&%C97,@870@=VAI8V@@97AC97!T
M:6]N(&AA;F1L:6YG(&1O;6%I;G,@87)E('-E="!U<"P@86YD('1H97)E)W,@
M;F\@=V%Y('1H870@8VAA;F=I;F<@82!M86-R;R!W:6QL(&UO9&EF>2!T:&4@
M8F5H879I;W(@;V8@86X@86QR96%D>2!C;VUP:6QE9"!M;V1U;&4Z('1H97D@
M8V%L;"!?3EA!9&1(86YD;&5R*"DL('1H97)E)W,@;F\@8VAA;F=I;F<@:70L
M(&%N9"!I="!L96%D<R!T;R!D:7-A<W1E<B`H=V4@=&AE;B!H879E("IT;V\@
M;6%N>2H@97AC97!T:6]N(&-H86EN<R!I;G-T96%D(&]F7`IT;V\@9F5W*2Y<
M"EP*"DET)W,@96%S>2!T;R!R961I<F5C="!C86QL<R!T;R!?3EA286ES945R
M<F]R*"D@=&\@;7D@7T9(4F%I<V5%<G)O<B@I+"!S:6YC92!T:&5R92=S(&$@
M<'5B;&ES:&5D('=A>2!T;R!D;R!I="P@8G5T($D@"FYE960@=&\@9&\@:70@
M9F]R(%].6$%D9$AA;F1L97(H*2!A;F0@7TY84F5M;W9E2&%N9&QE<B@I('1O
M;RP@86YD($D@8V%N)W0@=&AI;FL@;V8@82!W87D@=&\@9&\@:70N($UY('%U
M97-T:6]N(&ES('-I;7!L90HZ(&%M($D@=')Y:6YG('1H92!I;7!O<W-I8FQE
M/R`@*'=H:6-H('=O=6QD(&UE86X@:70G<R!T:6UE(&9O<B!T:&4@;65G82UM
M97-S>2!S;VQU=&EO;BP@8G5T($DG9"!L:6ME('1O(&%V;VED(&ET(&EF($D@
M8V]U;&0I+B!$;V5S(&%N>6)O9'D@:VYO=R!W:&%T('1H92!U;F1O8W5M96YT
M960@<WEM8F]L<R!?3EA!9&1!;'1(86YD;&5R(&%N9"!?3EA296UO=F5!;'1(
M86YD;&5R(&EN(&5X8V5P="YO(&EN<VED92!L:6)S>7,@87)E(&9O<C]<"EP*
1"49E9&5R:6-O"EP*7`H*?0IO
`