prevent from aborting on too large stack size
authorgc <gc>
Mon, 14 Apr 2008 16:51:25 +0000 (16:51 +0000)
committergc <gc>
Mon, 14 Apr 2008 16:51:25 +0000 (16:51 +0000)
ext/rbbooh.cc

index 02cba67..59e5057 100644 (file)
@@ -174,6 +174,8 @@ static VALUE modify_bg(VALUE self, VALUE state, VALUE color) {
         return self;
 }
 
+static int counter = 0;
+
 // internalize pixbuf loading for 30% more speedup
 static VALUE load_not_freezing_ui(VALUE self, VALUE path, VALUE interruptable, VALUE area_prepared_signal_id) {
         int interruptable_ = RTEST(interruptable);
@@ -182,26 +184,33 @@ static VALUE load_not_freezing_ui(VALUE self, VALUE path, VALUE interruptable, V
         GdkPixbufLoader* loader = GDK_PIXBUF_LOADER(RVAL2GOBJ(self));
         GError* error = NULL;
         FILE* f = fopen(RVAL2CSTR(path), "r");
+        counter++;
         while ((amount = fread(buf, 1, 65536, f)) > 0) {
                 if (!gdk_pixbuf_loader_write(loader, (const guchar*) buf, amount, &error)) {
                         fclose(f);
                         RAISE_GERROR(error);
                 }
-                while (gtk_events_pending()) {
-                        gtk_main_iteration();
-                }
-                if (interruptable_ && RTEST(rb_eval_string("$interrupt_loading"))) {
-                        // interrupted, case when the user clicked/keyboarded too quickly for this image to
-                        // display; we cancel this loading, but before we disconnect the area-prepared
-                        // signal handler, else the call to gdk_pixbuf_loader_get_pixbuf will take ages
-                        // (between 100 and 400 ms on my p4 for a large photo!)
-                        g_signal_handler_disconnect(loader, NUM2INT(area_prepared_signal_id));
-                        gdk_pixbuf_loader_close(loader, NULL);
-                        fclose(f);
-                        return Qfalse;
+                if (counter < 52) {
+                        // if the user scrolls too fast between thumbnails, there can be large amount of recursions,
+                        // and program may abort - probably on exhausted stack size; this figure is completely empiric
+                        while (gtk_events_pending()) {
+                                gtk_main_iteration();
+                        }
+                        if (interruptable_ && RTEST(rb_eval_string("$interrupt_loading"))) {
+                                // interrupted, case when the user clicked/keyboarded too quickly for this image to
+                                // display; we cancel this loading, but before we disconnect the area-prepared
+                                // signal handler, else the call to gdk_pixbuf_loader_get_pixbuf will take ages
+                                // (between 100 and 400 ms on my p4 for a large photo!)
+                                g_signal_handler_disconnect(loader, NUM2INT(area_prepared_signal_id));
+                                gdk_pixbuf_loader_close(loader, NULL);
+                                fclose(f);
+                                counter--;
+                                return Qfalse;
+                        }
                 }
         }
         fclose(f);
+        counter--;
         return Qtrue;
 }