Thread.bind(sym, val) { ... }

e$B%9%l%C%IJQ?t$r0l;~E*$K@_Dj$9$k%a%=%C%I$r2C$($k$N$O$I$&$G$7$g$&$+!#e(B

e$B$?$H$($Pe(B Thread#bind(sym, val) { … } e$B$H$7$F!“e(B
e$B%V%m%C%/$r8F$S=P$7$F$$$k$”$$$@!"%9%l%C%IJQ?te(B sym e$B$re(B
val e$B$K@_Dj$9$k!"$H$$$&$h$&$J$b$N$G$9!#e(B

p Thread.current[:a] # nil
Thread.current.bind(:a, 100) {
p Thread.current[:a] # 100
}
p Thread.current[:a] # nil e$B$KLa$ke(B

e$B%9%l%C%IJQ?t$O$3$N$h$&$J;H$$J}$,B?$$$N$G!"%a%=%C%I$,$"$C$F$b$$$$e(B
e$B$h$&$K;W$$$^$9!#e(B

e$B$J$*!"e(Bbind e$B0J30$NL>A0$H$7$F$Oe(B let e$B$,;W$$Ib$+$S$^$9!#e(B

e$B$^$?!“e(BThread e$B$8$c$J$/$Fe(B Fiber
e$B$8$c$J$$$+!”$H$$$&OC$O$"$k$+$b$7$l$^$;$s!#e(B

% svn diff --diff-cmd diff -x ‘-u -p’
Index: thread.c

— thread.c (revision 28780)
+++ thread.c (working copy)
@@ -2071,6 +2071,59 @@ rb_thread_aset(VALUE self, VALUE id, VAL
return rb_thread_local_aset(self, rb_to_id(id), val);
}

+struct rb_thread_bind_arg {

  • VALUE thread;
  • ID id;
  • VALUE old;
    +};

+static VALUE
+rb_thread_bind_ensure(VALUE _arg)
+{

  • struct rb_thread_bind_arg *arg = (struct rb_thread_bind_arg *)_arg;
  • rb_thread_local_aset(arg->thread, arg->id, arg->old);
  • return Qnil;
    +}

+/*

    • call-seq:
    • thr.bind(sym, obj) { ... }
      
    • Set the attribute temporally.
    • This method sets the attribute sym of the thread thr as obj
    • between the block is called.
    • It restore the attribute after the block exits
    • even if an exception is raised in the block.
    • This method returns the value of the block.
    • Thread.current.bind(:a, 1) {
      
    •   # Thread.current[:a] is 1.
      
    •   Thread.current.bind(:a, 2) {
      
    •     # Thread.current[:a] is 2.
      
    •     Thread.current.bind(:a, 3) {
      
    •       # Thread.current[:a] is 3.
      
    •     }
      
    •     # Thread.current[:a] is 2.
      
    •   }
      
    •   # Thread.current[:a] is 1.
      
    • }
      
  • */

+static VALUE
+rb_thread_bind(VALUE thread, VALUE sym, VALUE val)
+{

  • ID id = rb_to_id(sym);
  • struct rb_thread_bind_arg arg;
  • arg.thread = thread;
  • arg.id = id;
  • arg.old = rb_thread_local_aref(thread, id);
  • rb_thread_local_aset(thread, id, val);
  • return rb_ensure(rb_yield, Qnil, rb_thread_bind_ensure,
    (VALUE)&arg);
    +}

/*

  • call-seq:
  • thr.key?(sym)   -> true or false
    

@@ -4202,6 +4255,7 @@ Init_Thread(void)
rb_define_method(rb_cThread, “wakeup”, rb_thread_wakeup, 0);
rb_define_method(rb_cThread, “[]”, rb_thread_aref, 1);
rb_define_method(rb_cThread, “[]=”, rb_thread_aset, 2);

  • rb_define_method(rb_cThread, “bind”, rb_thread_bind, 2);
    rb_define_method(rb_cThread, “key?”, rb_thread_key_p, 1);
    rb_define_method(rb_cThread, “keys”, rb_thread_keys, 0);
    rb_define_method(rb_cThread, “priority”, rb_thread_priority, 0);

p Thread.current[:a] # nil e$B$KLa$ke(B

e$B%9%l%C%IJQ?t$O$3$N$h$&$J;H$$J}$,B?$$$N$G!"%a%=%C%I$,$"$C$F$b$$$$e(B
e$B$h$&$K;W$$$^$9!#e(B

e$B$J$*!"e(Bbind e$B0J30$NL>A0$H$7$F$Oe(B let e$B$,;W$$Ib$+$S$^$9!#e(B

e$B$^$?!“e(BThread e$B$8$c$J$/$Fe(B Fiber e$B$8$c$J$$$+!”$H$$$&OC$O$"$k$+$b$7$l$^$;$s!#e(B

Fibere$B$,$$$$$J$!!&!&!&!&e(B

e$B$=$l$O$=$l$H$7$F!"%a%=%C%I$G$d$k$h$j$b%9%l%C%I%m!<%+%kJQ?t$r@k8@$9$ke(B
e$B9=J8$D$/$C$?$[$&$,$&$l$7$$$h$&$J5$$,$A$g$C$H$@$1$7$^$9!#e(B
e$B$?$+$,JQ?t#1$D$N$?$a$K!"%$%s%G%s%H$,0lCJ?<$/$J$k$H$$$&$N$,$I$&$K$b!&!&!&e(B

2010/7/29 KOSAKI Motohiro [email protected]:

e$B%9%l%C%IJQ?t$r0l;~E*$K@_Dj$9$k%a%=%C%I$r2C$($k$N$O$I$&$G$7$g$&$+!#e(B

e$B;?@.$G$9!#e(BTLSe$B!Je(Bthread local
storagee$B!K$O$3$NMQES0J30$G$N@5$7$$;HMQK!$r;We(B
e$B$$$D$-$^$;$s!JH?O@Jg=8!K!#$N$G!“@5$7$$;HMQK!$r;H$$$d$9$/$9$k$N$K;?@.$7$^e(B
e$B$9!#$^$?Ds0F$Ne(BAPIe$B$b!“e(BRubye$B$Ne(Bblock +
ensuree$B%Q%?!<%s$rA[5/$5$;!”!V85$KLa$ke(B
e$B$s$@$h!W46$,$”$C$F$h$$$H;W$$$^$9!#e(B

e$B$?$H$($Pe(B Thread#bind(sym, val) { … } e$B$H$7$F!“e(B
e$B%V%m%C%/$r8F$S=P$7$F$$$k$”$$$@!“%9%l%C%IJQ?te(B sym e$B$re(B
val e$B$K@_Dj$9$k!”$H$$$&$h$&$J$b$N$G$9!#e(B

e$B$,!“Kh2se(B”.current."e$B$r=q$/$N$,%$%^%$%A$+$J!<!#e(BThread.currente$B0J30$Ne(BTLSe$B$C$Fe(B
e$B;H$o$J$$$G$9$h$M!#$7$+$7$h$$e(BAPIe$B$r;W$$$D$-$^$;$s!#!#!#C/$+!#e(B

e$B$^$?!“e(BThread e$B$8$c$J$/$Fe(B Fiber e$B$8$c$J$$$+!”$H$$$&OC$O$"$k$+$b$7$l$^$;$s!#e(B

Fibere$B$,$$$$$J$!!&!&!&!&e(B

Fibere$B$h$/$o$+$i$J$$!#!#!#e(B

e$B$=$l$O$=$l$H$7$F!“%a%=%C%I$G$d$k$h$j$b%9%l%C%I%m!<%+%kJQ?t$r@k8@$9$ke(B
e$B9=J8$D$/$C$?$[$&$,$&$l$7$$$h$&$J5$$,$A$g$C$H$@$1$7$^$9!#e(B
e$B$?$+$,JQ?t#1$D$N$?$a$K!”%$%s%G%s%H$,0lCJ?<$/$J$k$H$$$&$N$,$I$&$K$b!&!&!&e(B

e$B$[$H$s$I$,e(B

Thread.current.bind(:a, 100) do
do_tls_depending_work
end

e$B$H$+$J$N$G!"$$$$$s$8$c$J$$$G$7$g$&$+!#e(BTLSe$B;H$&$h$&$J=hM}$Oe(Binlinee$B$8$c=q$1e(B
e$B$J$$$G$7$g$&!#e(B

e$B$I$A$i$+$H$$$&$H;?@.$G$9!#e(B

(2010/07/30 7:32), Yukihiro M. wrote:

|e$B%9%l%C%IJQ?t$O$3$N$h$&$J;H$$J}$,B?$$$N$G!"%a%=%C%I$,$"$C$F$b$$$$e(B
|e$B$h$&$K;W$$$^$9!#e(B

e$BB?$$$s$G$9$+!#8D?ME*$K$O%9%l%C%IJQ?t$O%9%l%C%I%9%3!<%W$N%0%m!<e(B
e$B%P%kJQ?t$H$7$F$@$1;H$$!"%9%3!<%W$N$"$k$h$&$J;H$$J}$N7P83$O$Je(B
e$B$$$s$G$9$,!#e(B

Rubye$B$Ge(BTLSe$B$r;H$&$H$$$C$F;W$$=P$9$N$Oe(Binspecte$B$de(Bpretty_inspecte$B$Ne(Brecursion
check
e$B$G!"$3$&$$$C$?$b$N$O$^$5$K%9%3!<%W$N$"$k;H$$J}$@$H;W$$$^$9!#e(B

e$B$^$“e(Binspecte$B$Ne(B…e$B$r=P$9$N$,K\Ev$Ke(BTLSe$B$rMQ$$$F<B8=$5$l$k$Y$-$+$K$O5DO@$,$”$k$H$3e(B
e$B$m$@$H;W$$$^$9$,!"$=$l$O$=$l$H$7$F%9%3!<%W$N%K!<%:<+BN$O$"$k$N$G!"$3$N5!G=$Oe(B
e$B$"$C$F$b$$$$$+$J$"$H;W$$$^$9!#;d$N7P83$H$7$F$O$+$D$Fe(Bmethod_missinge$B$NCf$GFH<+$Ke(B
e$B%a%=%C%I%G%#%9%Q%C%A$r$7$h$&$H$7$?$H$-$K!“e(Bmethod_missinge$B$,L58B:F5”$K$J$k$N$rH/e(B
e$B8+$9$kMQES$G;w$?$h$&$J;H$$J}$r$7$^$7$?!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41893] thread.bind(sym, val) { … }”
on Thu, 29 Jul 2010 18:40:43 +0900, Tanaka A. [email protected]
writes:

|e$B%9%l%C%IJQ?t$r0l;~E*$K@_Dj$9$k%a%=%C%I$r2C$($k$N$O$I$&$G$7$g$&$+!#e(B
|
|e$B$?$H$($Pe(B Thread#bind(sym, val) { … } e$B$H$7$F!“e(B
|e$B%V%m%C%/$r8F$S=P$7$F$$$k$”$$$@!“%9%l%C%IJQ?te(B sym e$B$re(B
|val e$B$K@_Dj$9$k!”$H$$$&$h$&$J$b$N$G$9!#e(B
|
| p Thread.current[:a] # nil
| Thread.current.bind(:a, 100) {
| p Thread.current[:a] # 100
| }
| p Thread.current[:a] # nil e$B$KLa$ke(B
|
|e$B%9%l%C%IJQ?t$O$3$N$h$&$J;H$$J}$,B?$$$N$G!“%a%=%C%I$,$”$C$F$b$$$$e(B
|e$B$h$&$K;W$$$^$9!#e(B

e$BB?$$$s$G$9$+!#8D?ME*$K$O%9%l%C%IJQ?t$O%9%l%C%I%9%3!<%W$N%0%m!<e(B
e$B%P%kJQ?t$H$7$F$@$1;H$$!“%9%3!<%W$N$”$k$h$&$J;H$$J}$N7P83$O$Je(B
e$B$$$s$G$9$,!#e(B

2010e$BG/e(B7e$B7ne(B30e$BF|e(B7:32 Yukihiro M.
[email protected]:

e$BB?$$$s$G$9$+!#8D?ME*$K$O%9%l%C%IJQ?t$O%9%l%C%I%9%3!<%W$N%0%m!<e(B
e$B%P%kJQ?t$H$7$F$@$1;H$$!“%9%3!<%W$N$”$k$h$&$J;H$$J}$N7P83$O$Je(B
e$B$$$s$G$9$,!#e(B

e$B$&$%$`!“D4$YD>$7$F$_$k$H!”$?$7$+$K$=$s$J$KB?$/$J$$$N$+$b$7$l$^$;$s!#e(B

e$BC5$7$F$_$k$H0J2<$/$i$$$,8+$D$+$j$^$9!#e(B

  • lib/webrick/server.rb e$B$Ne(B Thread.current[:WEBrickSocket]
  • lib/drb/drb.rb e$B$Ne(B Thread.current[:drb_untaint]
  • ext/pathname/lib/pathname.rb e$B$Ne(B
    Thread.current[:pathname_sub_matchdata]

pp (e$B$de(B inspect)
e$B$G$O!“%9%l%C%IJQ?t$=$l<+BN$O0l2s@_Dj$7$?$iJQ$($^$;$s$M!#e(B
e$BJQ99!&2sI|$O@_Dj$7$?%O%C%7%e$NCf?H$KBP$7$F9T$&$N$G!”$=$l$Oe(B
Thread#bind e$B$Ge(B
e$BBP1~$9$k$b$N$G$O$J$5$=$&$G$9!#e(B

e$BDs0FA0$KD4$YD>$7$F$_$k$Y$-$@$C$?$+!#e(B

2010/7/30 Tanaka A. [email protected]:

e$BB?$$$s$G$9$+!#8D?ME*$K$O%9%l%C%IJQ?t$O%9%l%C%I%9%3!<%W$N%0%m!<e(B
e$B%P%kJQ?t$H$7$F$@$1;H$$!“%9%3!<%W$N$”$k$h$&$J;H$$J}$N7P83$O$Je(B
e$B$$$s$G$9$,!#e(B

e$B$&$%$`!“D4$YD>$7$F$_$k$H!”$?$7$+$K$=$s$J$KB?$/$J$$$N$+$b$7$l$^$;$s!#e(B

e$B0l1~!“$=$&$$$&;H$$J}$NNc$r!#e(B
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/lib/soap/mapping/mapping.rb?view=markup
e$B$N!“2<$N$[$&$K$”$ke(Bprotect_threadvarse$B$,Dj5A$G!”>e$N$[$&$KMxMQNc$,$“$j$^e(B
e$B$9!#e(Bobj2soape$B!“e(Bsoap2obje$B6&$K:F5”$9$k$N$G!”%9%3!<%W$r:n$j$^$9!#e(B

pp (e$B$de(B inspect) e$B$G$O!"%9%l%C%IJQ?t$=$l<+BN$O0l2s@_Dj$7$?$iJQ$($^$;$s$M!#e(B
e$BJQ99!&2sI|$O@_Dj$7$?%O%C%7%e$NCf?H$KBP$7$F9T$&$N$G!"e(B

Threade$B%$%s%9%?%s%9$,;H$$<N$F$N$3$H$,B?$/!“%0%m!<%P%kJQ?tE*$K;H$C$F$b5$$Ke(B
e$B$J$i$J$$!”$H$$$&$3$H$O$“$k$+$b$7$l$^$;$s!#:F5”$;$:!"L>A0>WFM$,L5$1$l$P0Ue(B
e$BL#$J$$$7!#e(B

e$B$=$l$Oe(B Thread#bind e$B$Ge(B
e$BBP1~$9$k$b$N$G$O$J$5$=$&$G$9!#e(B

Hashe$BE*$J$b$N$X$NBeF~$G%9%3!<%W$N$h$&$J;H$$J}!"$HHFMQ2=$9$l$P$h$$!)e(B
let(Thread.current, :sym => var) {}
e$B$H$+!#e(B