[macruby-changes] [5231] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Feb 11 19:27:32 PST 2011


Revision: 5231
          http://trac.macosforge.org/projects/ruby/changeset/5231
Author:   lsansonetti at apple.com
Date:     2011-02-11 19:27:31 -0800 (Fri, 11 Feb 2011)
Log Message:
-----------
fix a race condition bug when generating internal class names where concurrent access would cause runtime problems

Modified Paths:
--------------
    MacRuby/trunk/class.c
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h

Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c	2011-02-10 22:43:58 UTC (rev 5230)
+++ MacRuby/trunk/class.c	2011-02-12 03:27:31 UTC (rev 5231)
@@ -148,31 +148,19 @@
 static VALUE
 rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass)
 {
-    char ocname[128];
-
-    if (name == NULL) {
-	static long anon_count = 1;
-    	snprintf(ocname, sizeof ocname, "RBAnonymous%ld", ++anon_count);
+    char ocname[512] = { '\0' };
+    if (!rb_vm_generate_objc_class_name(name, ocname, sizeof ocname)) {
+	goto no_more_classes;
     }
-    else {
-	if (objc_getClass(name) != NULL) {
-	    long count = 1;
-	    snprintf(ocname, sizeof ocname, "RB%s", name);
-	    while (objc_getClass(ocname) != NULL) {
-		snprintf(ocname, sizeof ocname, "RB%s%ld", name, ++count);
-	    }
-	}
-	else {
-	    strncpy(ocname, name, sizeof ocname);
-	}
-    }
 
     if (super == 0) {
 	super = rb_cObject;
     }
 
     Class ocklass = objc_allocateClassPair((Class)super, ocname, sizeof(id));
-    assert(ocklass != NULL);
+    if (ocklass == NULL) {
+	goto no_more_classes;
+    }
 
     long version_flag = RCLASS_IS_RUBY_CLASS;
     if (flags == T_MODULE) {
@@ -187,6 +175,9 @@
     }
 
     return (VALUE)ocklass;
+
+no_more_classes:
+    rb_raise(rb_eRuntimeError, "can't create new classes");
 }
 
 VALUE

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2011-02-10 22:43:58 UTC (rev 5230)
+++ MacRuby/trunk/vm.cpp	2011-02-12 03:27:31 UTC (rev 5231)
@@ -4799,6 +4799,37 @@
     return GET_VM()->get_current_class();
 }
 
+extern "C"
+bool
+rb_vm_generate_objc_class_name(const char *name, char *buf, size_t buflen)
+{
+    RoxorCoreLock lock;
+
+    if (name == NULL) {
+	static unsigned long anon_count = 1;
+	if (anon_count == ULONG_MAX) {
+	    return false;
+	}
+	snprintf(buf, buflen, "RBAnonymous%ld", ++anon_count);
+    }
+    else {
+	if (objc_getClass(name) != NULL) {
+	    unsigned long count = 1;
+	    snprintf(buf, buflen, "RB%s", name);
+	    while (objc_getClass(buf) != NULL) {
+		if (count == ULONG_MAX) {
+		    return false;
+		}
+		snprintf(buf, buflen, "RB%s%ld", name, ++count);
+	    }
+	}
+	else {
+	    strncpy(buf, name, buflen);
+	}
+    }
+    return true;
+}
+
 static VALUE
 builtin_ostub1(IMP imp, id self, SEL sel, int argc, VALUE *argv)
 {

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2011-02-10 22:43:58 UTC (rev 5230)
+++ MacRuby/trunk/vm.h	2011-02-12 03:27:31 UTC (rev 5231)
@@ -491,6 +491,9 @@
 
 bool rb_vm_aot_feature_load(const char *name);
 
+bool rb_vm_generate_objc_class_name(const char *name, char *buf,
+	size_t buflen);
+
 void rb_vm_raise(VALUE exception);
 void rb_vm_raise_current_exception(void);
 VALUE rb_vm_current_exception(void);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20110211/bd5379d8/attachment.html>


More information about the macruby-changes mailing list