# Autoloading static linked extension

**URL:** <https://www.ruby-forum.com/t/autoloading-static-linked-extension/79726>\
**Category:** Development\
**Created:** [December 18, 2006, 3:47pm UTC](https://www.ruby-forum.com/t/autoloading-static-linked-extension/79726 "2006-12-18T15:47:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [December 18, 2006, 3:47pm UTC](https://www.ruby-forum.com/t/autoloading-static-linked-extension/79726/1 "2006-12-18T15:47:24Z")

</div>

e$B$J$+$@$G$9!#e(B

[http://moonrock.jp/~don/d/200612.html#d08\_t2](http://moonrock.jp/~don/d/200612.html#d08_t2) e$B$N7o$G$9$,!"e(B  
Init\_ext()e$B$G$Oe(Bloading\_tble$B$KF~$i$J$$$N$,860x$G$9!#e(B

e$B$H$j$"$($:e(B[ruby-dev:29523]e$B$N:]$K:n$C$?%Q%C%A$G$9!#e(Bext/extmk.rb  
e$B$Oe(B1.8e$B$b6&DL!#e(B

# Index: eval.c

RCS file: /pub/cvs/ruby/eval.c,v  
retrieving revision 1.616.2.194  
diff -U 2 -p -r1.616.2.194 eval.c  
— eval.c 10 Sep 2006 00:18:39 -0000 1.616.2.194  
+++ eval.c 13 Sep 2006 02:05:31 -0000  
@@ -6927,5 +6927,14 @@ static st\_table \*loading\_tbl;  
#endif

-static char \*  
+  
+static const char \*const loadable\_ext[] = {

- “.rb”, DLEXT,  
+#ifdef DLEXT2
- DLEXT2,  
+#endif
- 0  
+};
- 

+static int  
rb\_feature\_p(feature, ext, rb)  
const char \*feature, \*ext;  
@@ -6933,5 +6942,5 @@ rb\_feature\_p(feature, ext, rb)  
{  
VALUE v;

- char \*f, \*e;

- const char \*f, \*e;  
long i, len, elen;

@@ -6947,5 +6956,6 @@ rb\_feature\_p(feature, ext, rb)  
v = RARRAY(rb\_features)-\>ptr[i];  
f = StringValuePtr(v);

- if (strncmp(f, feature, len) != 0) continue;

- if (RSTRING\_LEN(v) \< len || strncmp(f, feature, len) != 0)
- 

```
  continue;

```

if (!\*(e = f + len)) {  
if (ext) continue;  
@@ -6960,32 +6970,32 @@ rb\_feature\_p(feature, ext, rb)  
}  
}
- if (loading\_tbl) {
- e = ext;
- if (!st\_lookup(loading\_tbl, (st\_data\_t)feature, 0)) {
- 

```
  char *buf;

```

- 
- 

```
  if (ext) return 0;

```

- 

```
  buf = ALLOCA_N(char, len+8);

```

- 

```
  strcpy(buf, feature);

```

- 

```
  for (i = 0; (e = loadable_ext[i]) != 0; i++) {

```

- 

```
  strcpy(buf + len, loadable_ext[i]);

```

- 

```
  if (st_lookup(loading_tbl, (st_data_t)buf, 0)) {

```

- 

```
      break;

```

- 

```
  }

```

- 

```
  }

```

- }
- return !e ? ‘u’ : strcmp(e, “.rb”) ? ‘s’ : ‘r’;
- }  
return 0;  
}

-static const char \*const loadable\_ext[] = {

- “.rb”, DLEXT,  
-#ifdef DLEXT2
- DLEXT2,  
-#endif
- 0  
-};
- 

int  
rb\_provided(feature)  
const char \*feature;  
{

- int i;
- char \*buf;

- int c;

- if (!loading\_tbl) return Qfalse;
- if (st\_lookup(loading\_tbl, (st\_data\_t)feature, 0)) return Qtrue;
- buf = ALLOCA\_N(char, strlen(feature)+8);
- strcpy(buf, feature);
- for (i=0; ; i++) {
- if (!loadable\_ext[i]) break;
- strcpy(buf+strlen(feature), loadable\_ext[i]);
- if (st\_lookup(loading\_tbl, (st\_data\_t)buf, 0)) return Qtrue;  
}  
return Qfalse;  
@@ -7006,17 +7016,39 @@ rb\_provide(feature)  
}

-static int  
-load\_wait(ftptr)

- char \*ftptr;  
+static char \*  
+load\_lock(ftptr)

- const char \*ftptr;  
{  
st\_data\_t th;

- if (!loading\_tbl) return Qfalse;
- if (!st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th)) return Qfalse;

- if (!loading\_tbl ||
- !st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th))
- {
- /\* loading ruby library should be serialized. \*/
- if (!loading\_tbl) {
- 

```
  loading_tbl = st_init_strtable();

```

- }
- /\* partial state \*/
- ftptr = ruby\_strdup(ftptr);
- st\_insert(loading\_tbl, (st\_data\_t)ftptr, (st\_data\_t)curr\_thread);
- return (char \*)ftptr;
- }  
do {

- if ((rb\_thread\_t)th == curr\_thread) return Qtrue;

- if ((rb\_thread\_t)th == curr\_thread) return 0;  
CHECK\_INTS;  
} while (st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th));

- return Qtrue;

- return 0;  
+}
- 

+static void  
+load\_unlock(const char \*ftptr)  
+{

- if (ftptr) {
- st\_data\_t key = (st\_data\_t)ftptr;
- 
- if (st\_delete(loading\_tbl, &key, 0)) {
- 

```
  free((char *)key);

```

- }
- }  
}

@@ -7149,16 +7181,9 @@ rb\_require\_safe(fname, safe)  
found = search\_required(fname, &feature, &path);  
if (found) {

- 

```
  if (!path || load_wait(RSTRING(feature)->ptr)) {

```

- 

```
  if (!path || !(ftptr = load_lock(RSTRING_PTR(feature)))) {
  result = Qfalse;
  }
  else {
  ruby_safe_level = 0;

```

- 

```
  /* loading ruby library should be serialized. */

```

- 

```
  if (!loading_tbl) {

```

- 

```
      loading_tbl = st_init_strtable();

```

- 

```
  }

```

- 

```
  /* partial state */

```

- 

```
  ftptr = ruby_strdup(RSTRING_PTR(feature));

```

- 

```
  st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);
  switch (found) {
    case 'r':

```

@@ -7187,9 +7212,5 @@ rb\_require\_safe(fname, safe)  
SCOPE\_SET(saved.vmode);  
ruby\_safe\_level = saved.safe;

- if (ftptr) {
- if (st\_delete(loading\_tbl, (st\_data\_t _)&ftptr, 0)) { /_ loading done  
\*/
- 

```
  free(ftptr);

```

- }
- }

- load\_unlock(ftptr);  
if (state) JUMP\_TAG(state);  
if (NIL\_P(result)) {  
@@ -7210,4 +7231,22 @@ rb\_require(fname)  
}

+void  
+ruby\_init\_ext(name, init)

- const char \*name;
- void (\*init) \_((void));  
+{
- ruby\_current\_node = 0;
- ruby\_sourcefile = rb\_source\_filename(name);
- ruby\_sourceline = 0;
- ruby\_frame-\>callee = 0;
- ruby\_frame-\>this\_func = 0;
- VIS\_SET(VIS\_PUBLIC);
- if (load\_lock(name)) {
- (\*init)();
- rb\_provide(name);
- load\_unlock(name);
- }  
+}
- 

static void  
secure\_visibility(self)

# Index: eval.c

RCS file: /pub/cvs/ruby/eval.c,v  
retrieving revision 1.946  
diff -U 2 -p -r1.946 eval.c  
— eval.c 18 Sep 2006 01:58:59 -0000 1.946  
+++ eval.c 19 Sep 2006 04:55:21 -0000  
@@ -6821,9 +6821,18 @@ static st\_table \*loading\_tbl;  
#endif

- 

+static const char \*const loadable\_ext[] = {

- “.rb”, DLEXT,  
+#ifdef DLEXT2
- DLEXT2,  
+#endif
- 0  
+};
- 

static int  
rb\_feature\_p(const char \*feature, const char \*ext, int rb)  
{  
VALUE v;

- char \*f, \*e;

- const char \*f, \*e;  
long i, len, elen;

@@ -6839,5 +6848,6 @@ rb\_feature\_p(const char \*feature, const  
v = RARRAY\_PTR(rb\_features)[i];  
f = StringValuePtr(v);

- if (strncmp(f, feature, len) != 0) continue;

- if (RSTRING\_LEN(v) \< len || strncmp(f, feature, len) != 0)
- 

```
  continue;

```

if (!\*(e = f + len)) {  
if (ext) continue;  
@@ -6852,15 +6862,24 @@ rb\_feature\_p(const char \*feature, const  
}  
}
- if (loading\_tbl) {
- e = ext;
- if (!st\_lookup(loading\_tbl, (st\_data\_t)feature, 0)) {
- 

```
  char *buf;

```

- 
- 

```
  if (ext) return 0;

```

- 

```
  buf = ALLOCA_N(char, len+8);

```

- 

```
  strcpy(buf, feature);

```

- 

```
  for (i = 0; (e = loadable_ext[i]) != 0; i++) {

```

- 

```
  strcpy(buf + len, loadable_ext[i]);

```

- 

```
  if (st_lookup(loading_tbl, (st_data_t)buf, 0)) {

```

- 

```
      break;

```

- 

```
  }

```

- 

```
  }

```

- }
- return !e ? ‘u’ : strcmp(e, “.rb”) ? ‘s’ : ‘r’;
- }  
return 0;  
}

-static const char \*const loadable\_ext[] = {

- “.rb”, DLEXT,  
-#ifdef DLEXT2
- DLEXT2,  
-#endif
- 0  
-};
- 

static int search\_required(VALUE, VALUE \*);

@@ -6868,24 +6887,12 @@ int  
rb\_provided(const char \*feature)  
{

- int i;
- char \*buf;

- int c;  
VALUE fname;

- if (loading\_tbl) {
- if (st\_lookup(loading\_tbl, (st\_data\_t)feature, 0)) return Qtrue;
- buf = ALLOCA\_N(char, strlen(feature)+8);
- strcpy(buf, feature);
- for (i=0; loadable\_ext[i]; i++) {
- 

```
  strcpy(buf+strlen(feature), loadable_ext[i]);

```

- 

```
  if (st_lookup(loading_tbl, (st_data_t)buf, 0)) return Qtrue;

```

- }
- }
- if (search\_required(rb\_str\_new2(feature), &fname)) {

- if ((c = search\_required(rb\_str\_new2(feature), &fname)) != 0) {  
feature = RSTRING\_PTR(fname);

- if (rb\_feature\_p(feature, 0, Qfalse))
- 

```
  return Qtrue;

```

- if (loading\_tbl && st\_lookup(loading\_tbl, (st\_data\_t)feature, 0))

- if (rb\_feature\_p(feature, c ? strrchr(feature, ‘.’) : 0, Qfalse))  
return Qtrue;  
}  
@@ -6905,16 +6912,38 @@ rb\_provide(const char \*feature)  
}

-static int  
-load\_wait(char \*ftptr)  
+static char \*  
+load\_lock(const char \*ftptr)  
{  
st\_data\_t th;

- if (!loading\_tbl) return Qfalse;
- if (!st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th)) return Qfalse;

- if (!loading\_tbl ||
- !st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th))
- {
- /\* loading ruby library should be serialized. \*/
- if (!loading\_tbl) {
- 

```
  loading_tbl = st_init_strtable();

```

- }
- /\* partial state \*/
- ftptr = ruby\_strdup(ftptr);
- st\_insert(loading\_tbl, (st\_data\_t)ftptr, (st\_data\_t)curr\_thread);
- return (char \*)ftptr;
- }  
do {

- if ((rb\_thread\_t)th == curr\_thread) return Qtrue;

- if ((rb\_thread\_t)th == curr\_thread) return 0;  
CHECK\_INTS;  
} while (st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th));

- return Qtrue;

- return 0;  
+}
- 

+static void  
+load\_unlock(const char \*ftptr)  
+{

- if (ftptr) {
- st\_data\_t key = (st\_data\_t)ftptr;
- 
- if (st\_delete(loading\_tbl, &key, 0)) {
- 

```
  free((char *)key);

```

- }
- }  
}

@@ -7063,5 +7092,5 @@ rb\_require\_safe(VALUE fname, int safe)  
found = search\_required(fname, &path);  
if (found) {

- 

```
  if (!path || load_wait(RSTRING_PTR(path))) {

```

- 

```
  if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
  result = Qfalse;
  }

```

@@ -7105,9 +7134,5 @@ rb\_require\_safe(VALUE fname, int safe)  
POP\_CREF();  
POP\_SCOPE();

- if (ftptr) {
- if (st\_delete(loading\_tbl, (st\_data\_t _)&ftptr, 0)) { /_ loading done  
\*/
- 

```
  free(ftptr);

```

- }
- }

- load\_unlock(ftptr);  
if (state) JUMP\_TAG(state);  
if (NIL\_P(result)) {  
@@ -7127,4 +7152,20 @@ rb\_require(const char \*fname)  
}

+void  
+ruby\_init\_ext(const char \*name, void (\*init)(void))  
+{

- ruby\_current\_node = 0;
- ruby\_sourcefile = rb\_source\_filename(name);
- ruby\_sourceline = 0;
- ruby\_frame-\>callee = 0;
- ruby\_frame-\>this\_func = 0;
- VIS\_SET(VIS\_PUBLIC);
- if (load\_lock(name)) {
- (\*init)();
- rb\_provide(name);
- load\_unlock(name);
- }  
+}
- 

static void  
secure\_visibility(VALUE self)

# Index: ext/extmk.rb

RCS file: /pub/cvs/ruby/ext/extmk.rb,v  
retrieving revision 1.101  
diff -U 2 -p -r1.101 extmk.rb  
— ext/extmk.rb 16 Sep 2006 07:06:36 -0000 1.101  
+++ ext/extmk.rb 19 Sep 2006 04:55:28 -0000  
@@ -452,12 +452,9 @@ unless $extlist.empty?  
#include “ruby.h”

-#define init(func, name) { \

- void func \_((void)); \
- ruby\_sourcefile = src = rb\_source\_filename(name); \
- func(); \
- rb\_provide(src);   
-}  
+#define init(func, name) {void func \_((void)); ruby\_init\_ext(name,  
func);}

- 

+void ruby\_init\_ext \_((const char \*name, void (\*init)(void)));

-void Init\_ext \_((void))\n{\n char \*src;#$extinit}  
+void Init\_ext \_((void))\n{\n#$extinit}  
}  
if !modified?(extinit.c, MTIMES) || IO.read(extinit.c) != src

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [December 18, 2006, 4:15pm UTC](https://www.ruby-forum.com/t/autoloading-static-linked-extension/79726/2 "2006-12-18T16:15:28Z")

</div>

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

In message “Re: [ruby-dev:30023] autoloading static linked extension”  
on Mon, 18 Dec 2006 23:46:23 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|[http://moonrock.jp/~don/d/200612.html#d08\_t2](http://moonrock.jp/~don/d/200612.html#d08_t2) e$B$N7o$G$9$,!“e(B  
|Init\_ext()e$B$G$Oe(Bloading\_tble$B$KF~$i$J$$$N$,860x$G$9!#e(B  
|  
|e$B$H$j$”$($:e(B[ruby-dev:29523]e$B$N:]$K:n$C$?%Q%C%A$G$9!#e(Bext/extmk.rb  
|e$B$Oe(B1.8e$B$b6&DL!#e(B

e$B@5D\>!“;W$C$?$h$jBg$-$/$FCf?H$rA4ItM}2r$7$?$H$OCG8@$G$-$J$$$Ne(B  
e$B$G$9$,!”$H$j$"$($:?.$8$^$9!#%3%\_%C%H$7$F$b$i$($^$;$s$+!#e(BHEAD  
e$B$K!#e(Bknue$B$5$s$,!V$&$s!W$H8@$($Pe(B1\_8e$B$K$b!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [December 18, 2006, 11:44pm UTC](https://www.ruby-forum.com/t/autoloading-static-linked-extension/79726/3 "2006-12-18T23:44:49Z")

</div>

At Tue, 19 Dec 2006 00:14:15 +0900,  
matz wrote:

> e$B@5D\>!“;W$C$?$h$jBg$-$/$FCf?H$rA4ItM}2r$7$?$H$OCG8@$G$-$J$$$Ne(B  
> e$B$G$9$,!”$H$j$"$($:?.$8$^$9!#%3%\_%C%H$7$F$b$i$($^$;$s$+!#e(BHEAD  
> e$B$K!#e(Bknue$B$5$s$,!V$&$s!W$H8@$($Pe(B1\_8e$B$K$b!#e(B

e$B!!e(Brb\_provided() e$B$Ne(B if e$B%V%m%C%/$O3g8L$,H4$1$F$$$^$9$+!)e(B

e$B!!e(B1.8  
e$B$K$D$$$F$O\<j85$G%F%9%H$7$?$$$N$GJLES%C%A$r$\*4j$$$7$^$9!#e(B

–  
/  
/\_\_ \_\_ [Akinori.org](http://Akinori.org) / [MUSHA.org](http://MUSHA.org)  
/ ) ) ) ) / [FreeBSD.org](http://FreeBSD.org) / [Ruby-lang.org](http://Ruby-lang.org)  
Akinori MUSHA aka / (\_ / ( (\_\_( @ [iDaemons.org](http://iDaemons.org) / and.or.jp

“Different eyes see different things,  
Different hearts beat on different strings –  
But there are times for you and me when all such things agree”

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [December 20, 2006, 6:35pm UTC](https://www.ruby-forum.com/t/autoloading-static-linked-extension/79726/4 "2006-12-20T18:35:50Z")

</div>

e$B$J$+$@$G$9!#e(B

At Tue, 19 Dec 2006 07:43:02 +0900,  
Akinori MUSHA wrote in [ruby-dev:30027]:

> e$B!!e(Brb\_provided() e$B$Ne(B if e$B%V%m%C%/$O3g8L$,H4$1$F$$$^$9$+!)e(B

e$B$9$$$^$;$s!"H4$1$F$k$H$$$&$+!"D\>$7$+$1$@$C$?$h$&$G$9!#e(B

> e$B!!e(B1.8 e$B$K$D$$$F$O\<j85$G%F%9%H$7$?$$$N$GJLES%C%A$r$\*4j$$$7$^$9!#e(B

e$B$3$l$G$I$&$G$7$g$&$+!#e(B

# Index: eval.c

RCS file: /pub/cvs/ruby/src/ruby/eval.c,v  
retrieving revision 1.616.2.200  
diff -U 2 -p -r1.616.2.200 eval.c  
— eval.c 9 Dec 2006 12:40:17 -0000 1.616.2.200  
+++ eval.c 19 Dec 2006 15:51:06 -0000  
@@ -6930,5 +6930,14 @@ static st\_table \*loading\_tbl;  
#endif

-static char \*  
+  
+static const char \*const loadable\_ext[] = {

- “.rb”, DLEXT,  
+#ifdef DLEXT2
- DLEXT2,  
+#endif
- 0  
+};
- 

+static int  
rb\_feature\_p(feature, ext, rb)  
const char \*feature, \*ext;  
@@ -6936,5 +6945,5 @@ rb\_feature\_p(feature, ext, rb)  
{  
VALUE v;

- char \*f, \*e;

- const char \*f, \*e;  
long i, len, elen;

@@ -6947,30 +6956,42 @@ rb\_feature\_p(feature, ext, rb)  
elen = 0;  
}

- for (i = 0; i \< RARRAY(rb\_features)-\>len; ++i) {
- v = RARRAY(rb\_features)-\>ptr[i];

- for (i = 0; i \< RARRAY\_LEN(rb\_features); ++i) {
- v = RARRAY\_PTR(rb\_features)[i];  
f = StringValuePtr(v);

- if (strncmp(f, feature, len) != 0) continue;

- if (RSTRING\_LEN(v) \< len || strncmp(f, feature, len) != 0)
- 

```
  continue;

```

if (!\*(e = f + len)) {  
if (ext) continue;

- 

```
  return e;

```

- 

```
  return 'u';

```

}  
if (\*e != ‘.’) continue;  
if ((!rb || !ext) && (IS\_SOEXT(e) || IS\_DLEXT(e))) {

- 

```
  return e;

```

- 

```
  return 's';

```

}  
if ((rb || !ext) && (strcmp(e, “.rb”) == 0)) {

- 

```
  return e;

```

- 

```
  return 'r';

```

- }
- }
- if (loading\_tbl) {
- e = ext;
- if (!st\_lookup(loading\_tbl, (st\_data\_t)feature, 0)) {
- 

```
  char *buf;

```

- 
- 

```
  if (ext) return 0;

```

- 

```
  buf = ALLOCA_N(char, len+8);

```

- 

```
  strcpy(buf, feature);

```

- 

```
  for (i = 0; (e = loadable_ext[i]) != 0; i++) {

```

- 

```
  strcpy(buf + len, loadable_ext[i]);

```

- 

```
  if (st_lookup(loading_tbl, (st_data_t)buf, 0)) {

```

- 

```
      break;

```

- 

```
  }

```

- 

```
  }

```

}
- return !e ? ‘u’ : strcmp(e, “.rb”) ? ‘s’ : ‘r’;  
}  
return 0;  
}

-static const char \*const loadable\_ext[] = {

- “.rb”, DLEXT,  
-#ifdef DLEXT2
- DLEXT2,  
-#endif
- 0  
-};  
+static int search\_required(VALUE, VALUE \*, VALUE \*);

int  
@@ -6978,17 +6999,12 @@ rb\_provided(feature)  
const char \*feature;  
{

- int i;
- char \*buf;

- VALUE fname, path;

- if (!loading\_tbl) return Qfalse;
- if (st\_lookup(loading\_tbl, (st\_data\_t)feature, 0)) return Qtrue;
- buf = ALLOCA\_N(char, strlen(feature)+8);
- strcpy(buf, feature);
- for (i=0; ; i++) {
- if (!loadable\_ext[i]) break;
- strcpy(buf+strlen(feature), loadable\_ext[i]);
- if (st\_lookup(loading\_tbl, (st\_data\_t)buf, 0)) return Qtrue;

- if (search\_required(rb\_str\_new2(feature), &fname, &path) != 0) {
- feature = RSTRING\_PTR(fname);
- if (rb\_feature\_p(feature, strrchr(feature, ‘.’), Qfalse))
- 

```
  return Qtrue;

```

}  
return Qfalse;  
@@ -7009,17 +7025,39 @@ rb\_provide(feature)  
}

-static int  
-load\_wait(ftptr)

- char \*ftptr;  
+static char \*  
+load\_lock(ftptr)

- const char \*ftptr;  
{  
st\_data\_t th;

- if (!loading\_tbl) return Qfalse;
- if (!st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th)) return Qfalse;

- if (!loading\_tbl ||
- !st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th))
- {
- /\* loading ruby library should be serialized. \*/
- if (!loading\_tbl) {
- 

```
  loading_tbl = st_init_strtable();

```

- }
- /\* partial state \*/
- ftptr = ruby\_strdup(ftptr);
- st\_insert(loading\_tbl, (st\_data\_t)ftptr, (st\_data\_t)curr\_thread);
- return (char \*)ftptr;
- }  
do {

- if ((rb\_thread\_t)th == curr\_thread) return Qtrue;

- if ((rb\_thread\_t)th == curr\_thread) return 0;  
CHECK\_INTS;  
} while (st\_lookup(loading\_tbl, (st\_data\_t)ftptr, &th));

- return Qtrue;

- return 0;  
+}
- 

+static void  
+load\_unlock(const char \*ftptr)  
+{

- if (ftptr) {
- st\_data\_t key = (st\_data\_t)ftptr;
- 
- if (st\_delete(loading\_tbl, &key, 0)) {
- 

```
  free((char *)key);

```

- }
- }  
}

@@ -7063,14 +7101,14 @@ search\_required(fname, featurep, path)  
\*featurep = fname;  
\*path = 0;

- ext = strrchr(ftptr = RSTRING(fname)-\>ptr, ‘.’);

- ext = strrchr(ftptr = RSTRING\_PTR(fname), ‘.’);  
if (ext && !strchr(ext, ‘/’)) {  
if (strcmp(".rb", ext) == 0) {  
if (rb\_feature\_p(ftptr, ext, Qtrue)) return ‘r’;

- 

```
  if (*path = rb_find_file(fname)) return 'r';

```

- 

```
  if ((*path = rb_find_file(fname)) != 0) return 'r';
  return 0;

```

}  
else if (IS\_SOEXT(ext)) {  
if (rb\_feature\_p(ftptr, ext, Qfalse)) return ‘s’;

- 

```
  tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);

```

- 

```
  tmp = rb_str_new(RSTRING_PTR(fname), ext-RSTRING_PTR(fname));
  *featurep = tmp;

```

#ifdef DLEXT2  
@@ -7091,18 +7129,16 @@ search\_required(fname, featurep, path)  
else if (IS\_DLEXT(ext)) {  
if (rb\_feature\_p(ftptr, ext, Qfalse)) return ‘s’;

- 

```
  if (*path = rb_find_file(fname)) return 's';

```

- 

```
  if ((*path = rb_find_file(fname)) != 0) return 's';

```

}  
}  
tmp = fname;

- switch (type = rb\_find\_file\_ext(&tmp, loadable\_ext)) {

- type = rb\_find\_file\_ext(&tmp, loadable\_ext);
- \*featurep = tmp;
- switch (type) {  
case 0:

- if ((ext = rb\_feature\_p(ftptr, 0, Qfalse))) {
- 

```
  type = strcmp(".rb", ext);

```

- 

```
  break;

```

- }
- return 0;

- ftptr = RSTRING\_PTR(tmp);

- return rb\_feature\_p(ftptr, 0, Qfalse);

- \*featurep = tmp;  
ext = strrchr(ftptr = RSTRING(tmp)-\>ptr, ‘.’);  
if (rb\_feature\_p(ftptr, ext, !–type)) break;  
@@ -7152,16 +7188,9 @@ rb\_require\_safe(fname, safe)  
found = search\_required(fname, &feature, &path);  
if (found) {
- 

```
  if (!path || load_wait(RSTRING(feature)->ptr)) {

```

- 

```
  if (!path || !(ftptr = load_lock(RSTRING_PTR(feature)))) {
  result = Qfalse;
  }
  else {
  ruby_safe_level = 0;

```

- 

```
  /* loading ruby library should be serialized. */

```

- 

```
  if (!loading_tbl) {

```

- 

```
      loading_tbl = st_init_strtable();

```

- 

```
  }

```

- 

```
  /* partial state */

```

- 

```
  ftptr = ruby_strdup(RSTRING_PTR(feature));

```

- 

```
  st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);
  switch (found) {
    case 'r':

```

@@ -7190,9 +7219,5 @@ rb\_require\_safe(fname, safe)  
SCOPE\_SET(saved.vmode);  
ruby\_safe\_level = saved.safe;

- if (ftptr) {
- if (st\_delete(loading\_tbl, (st\_data\_t _)&ftptr, 0)) { /_ loading done  
\*/
- 

```
  free(ftptr);

```

- }
- }

- load\_unlock(ftptr);  
if (state) JUMP\_TAG(state);  
if (NIL\_P(result)) {  
@@ -7213,4 +7238,22 @@ rb\_require(fname)  
}

+void  
+ruby\_init\_ext(name, init)

- const char \*name;
- void (\*init) \_((void));  
+{
- ruby\_current\_node = 0;
- ruby\_sourcefile = rb\_source\_filename(name);
- ruby\_sourceline = 0;
- ruby\_frame-\>last\_func = 0;
- ruby\_frame-\>orig\_func = 0;
- SCOPE\_SET(SCOPE\_PUBLIC);
- if (load\_lock(name)) {
- (\*init)();
- rb\_provide(name);
- load\_unlock(name);
- }  
+}
- 

# static void secure\_visibility(self) Index: ext/extmk.rb

RCS file: /pub/cvs/ruby/src/ruby/ext/extmk.rb,v  
retrieving revision 1.44.2.37  
diff -U 2 -p -r1.44.2.37 extmk.rb  
— ext/extmk.rb 19 Oct 2006 16:03:45 -0000 1.44.2.37  
+++ ext/extmk.rb 19 Dec 2006 15:54:28 -0000  
@@ -452,12 +452,9 @@ unless $extlist.empty?  
#include “ruby.h”

-#define init(func, name) { \

- void func \_((void)); \
- ruby\_sourcefile = src = rb\_source\_filename(name); \
- func(); \
- rb\_provide(src);   
-}  
+#define init(func, name) {void func \_((void)); ruby\_init\_ext(name,  
func);}

- 

+void ruby\_init\_ext \_((const char \*name, void (\*init)(void)));

-void Init\_ext \_((void))\n{\n char \*src;#$extinit}  
+void Init\_ext \_((void))\n{\n#$extinit}  
}  
if !modified?(extinit.c, MTIMES) || IO.read(extinit.c) != src
