render_multi uses render_slices now, and seems to work
authorTero Marttila <terom@fixme.fi>
Mon, 09 Jun 2008 18:58:39 +0300
changeset 18 86f2e5b7191b
parent 17 8e8b56b0e0f5
child 19 d18606bb6f20
render_multi uses render_slices now, and seems to work

committer: Tero Marttila <terom@fixme.fi>
Makefile
http.c
render.c
render_mandelbrot.c
render_multi.c
render_remote.c
render_slices.c
render_slices.h
render_slices_struct.h
web_main.c
--- a/Makefile	Mon Jun 09 03:15:34 2008 +0300
+++ b/Makefile	Mon Jun 09 18:58:39 2008 +0300
@@ -1,7 +1,7 @@
 LDFLAGS = -Llib/libevent-dev/lib -levent -lpng
 CFLAGS = -Wall -g -Ilib/libevent-dev/include
 
-EXECS = render_file web_main render_node
+EXECS = file_main web_main node_main
 
 all: web_main file_main node_main
 
--- a/http.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/http.c	Mon Jun 09 18:58:39 2008 +0300
@@ -39,7 +39,7 @@
                         int_val = strtol(qarg->value, &cptr, 10);
 
                         if (*qarg->value == '\0' || *cptr != '\0' || int_val < 0)
-                            ERROR("invalid QARG_UINT: %s: %s -> %d", qarg->key, qarg->value, int_val);
+                            ERROR("invalid QARG_UINT: %s: %s -> %ld", qarg->key, qarg->value, int_val);
 
                         *((unsigned long int *) qarg_info->hqa_addr) = (unsigned long int) int_val;
 
--- a/render.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/render.c	Mon Jun 09 18:58:39 2008 +0300
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "render_internal.h"
+#include "render_struct.h"
 #include "render.h"
 
 int render_init (struct render *ctx, int mode) {
--- a/render_mandelbrot.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/render_mandelbrot.c	Mon Jun 09 18:58:39 2008 +0300
@@ -1,6 +1,6 @@
 
 #include "common.h"
-#include "render_internal.h"
+#include "render_struct.h"
 #include "render_mandelbrot.h"
 
 #define DETAIL 255
--- a/render_multi.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/render_multi.c	Mon Jun 09 18:58:39 2008 +0300
@@ -53,7 +53,7 @@
         // how many bytes we have already written into the current row
         size_t col;
 
-        // _render_multi_done called for this?
+        // passed in the last segment of data?
         int render_done;
         
         // a pointer to ourself
@@ -79,8 +79,8 @@
     // the render_slices thing
     struct render_slices slices;
 
-    // has render_png_done returned?
-    int png_done;
+    // has render_slices_done returned?
+    int slices_done;
 
     // buffer render_png output in this
     struct evbuffer *out_buf;
@@ -154,10 +154,9 @@
         ctx->cb_data(ctx->out_buf, ctx->cb_arg);
     
     // was that the last piece of PNG data?
-    if (ctx->png_done && evbuffer_get_length(ctx->out_buf) == 0) {
+    if (ctx->slices_done && evbuffer_get_length(ctx->out_buf) == 0) {
         // PNG data done!
         _render_multi_do_png_done(ctx);
-
     }
 }
 
@@ -188,21 +187,23 @@
         assert(ctx->nodes[i].render_remote == NULL);
         assert(ctx->nodes[i].col == 0);
     }
+    
+    // finish off the render_slices
+    if (render_slices_done(&ctx->slices))
+        ERROR("render_slices_done");
+    
+    // mark this as complete, all data is now in the out buffer
+    ctx->slices_done = 1;
 
-    // and that the PNG stuff is complete
-    assert(ctx->png_done);
-    
     // if that all the data handled now, we're done
     _render_multi_do_png_data(ctx);
 
     // don't free ourself, our user does that (probably already did, via render_png_done)
     return;
 
-/*
 error:    
-    / * render_png_done failed, probably because we didn't have enough data * /
+    /* render_slices_done -> render_png_done failed, probably because we didn't have enough data */
     _render_multi_do_fail(ctx, FAIL_PARTIAL);
-*/    
 }
 
 // the request completed abnormally. Flags:
@@ -301,17 +302,12 @@
             ERROR("read");
 
     } else if (ret == 0) {
-        // mark it as done
-        ctx->render_done = 1;
-        ctx->self->renders_done++;
-       
         // this ctx's remote render is done
         render_remote_done(ctx->render_remote);
         ctx->render_remote = NULL;
 
-        // we should only receive an EOF when ctx->col is zero or full
-        if (ctx->col != 0 || ctx->col != ctx->slice_width)
-            ERROR("incomplete data for slice %zu: %zu/%zu bytes", ctx->info->index, ctx->col, ctx->slice_width);
+        // count how many are done
+        ctx->self->renders_done++;
 
         // are all of them done?
         if (ctx->self->renders_done == ctx->self->node_count) {
@@ -324,44 +320,43 @@
         return;
     }
 
-    // check if we were expecting
-    
     // ok, we received some data normally
     ctx->col += ret;
 
-    // is our slice full now?
+    // is this segment full now?
     if (ctx->col == ctx->slice_width) {
-        // yes!
         int status;
         
+        // pass the segment in to render_slices
         if ((status = render_slices_segment_done(&ctx->self->slices, ctx->info->index)) == -1)
             ERROR("render_slices_segment_done");
-        
+
+        // reset the col marker
+        ctx->col = 0;
+
         // row done?
         if (status & SLICE_PROCESS_ROW) {
-            // XXX: ignore SLICE_PROCESS_ROW from render_slices_process_row
+            // process the row via render_slices
             status = render_slices_process_row(&ctx->self->slices);
-
-            // we should have SLICE_CONTINUE by now, unless the PNG is done
-            if (status & SLICE_CONTINUE) {
-                // clear the col values and reschedule the reads in case they were ~SLICE_CONTINUE
-                int i;
-                for (i = 0; i < ctx->self->node_count; i++) {
-                    ctx->self->nodes[i].col = 0;
-                    render_remote_reschedule(ctx->self->nodes[i].render_remote);
-                }
-            } else {
-                // XXX: assume render_slices_process_row doesn't return a SLICE_PROCESS_ROW alone
-                assert(status == 0);
-
-                ctx->self->png_done = 1;
-
-                // and wait for the EOF...
-            }
+            
         }
 
-        // if we got SLICE_CONTINUE here, I don't care, don't try and get another row now
-        // just fall through and reschedule
+        // do we need to continue?
+        if (status & SLICE_CONTINUE) {
+            // reschedule the reads in case they were ~SLICE_CONTINUE
+            int i;
+
+            for (i = 0; i < ctx->self->node_count; i++) {
+                // just don't reschedule those that are already EOF...
+                if (ctx->self->nodes[i].render_remote)
+                    render_remote_reschedule(ctx->self->nodes[i].render_remote);
+            }
+
+        } else {
+            // don't read any more data yet, we'll be rescheduled by someone else
+            return;
+
+        }
     }
 
     // ok, reschedule ourselves
--- a/render_remote.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/render_remote.c	Mon Jun 09 18:58:39 2008 +0300
@@ -9,7 +9,7 @@
 #include <event2/event_struct.h>
 #include <event2/bufferevent.h>
 
-#include "render_internal.h"    // for render_cmd_build
+#include "render_struct.h"    // for render_cmd_build
 #include "render_remote.h"
 #include "common.h"
 
--- a/render_slices.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/render_slices.c	Mon Jun 09 18:58:39 2008 +0300
@@ -113,41 +113,48 @@
 
 int render_slices_segment_done (struct render_slices *ctx, int index) {
     assert(index >= 0 && index < ctx->num_slices);
-    assert(ctx->slices_done < ctx->num_slices);
-    
-    // keep track of the number of full slices
-    ctx->slices_done++;
     
-    // is the row complete?
-    if (ctx->slices_done == ctx->num_slices) {
+    // our return status
+    int status = 0;
+
+    // keep track of the number of full segments in this row
+    ctx->segments_done++;
+    
+    // is this row complete?
+    if (ctx->segments_done == ctx->num_slices) {
         // the row is complete
-        ctx->slices_done = 0;
+        ctx->segments_done = 0;
+    
+        // once we fill up a row we can always call process_row
+        status |= SLICE_PROCESS_ROW;
         
-        // is the other row waiting for it to get processed?
+        // is the other row still waiting for it to get processed?
         if (ctx->done_row < 0) {
             // no, point the done_row at this row, point the render buffers to the unused row
             ctx->done_row = ctx->render_row;
             ctx->render_row = (ctx->render_row == 0 ? 1 : 0);
             
             int i ;
+
+            // update the remaining render buffers
             for (i = 0; i < ctx->num_slices; i++) {
                 ctx->slices[i].info.render_buf = ctx->rows[ctx->render_row] + ctx->slices[i].row_offset;
             }
             
             // can now continue rendering as well as call process_row
-            return SLICE_PROCESS_ROW & SLICE_CONTINUE;
+            status |= SLICE_CONTINUE;
 
         } else {
             // cannot continue rendering, need to have process_row complete first
-            return SLICE_PROCESS_ROW;
 
         }
 
     } else {
         // the row is not complete, do not render the next segment, do not call process_row
-        return 0;
 
     }
+
+    return status;
 }
 
 int render_slices_process_row (struct render_slices *ctx) {
@@ -159,7 +166,7 @@
     
     // mark the row as processed
     ctx->done_row = -1;
-
+    
     // ok, but don't call me again until I tell you to.
     return SLICE_CONTINUE;
 
@@ -168,4 +175,14 @@
     return -1;
 }   
 
+int render_slices_done (struct render_slices *ctx) {
+    // finish off render_png
+    if (render_png_done(&ctx->png_info))
+        ERROR("render_png_done");
+    
+    return 0;
 
+error:
+    render_slices_free(ctx);
+    return -1;
+}
--- a/render_slices.h	Mon Jun 09 03:15:34 2008 +0300
+++ b/render_slices.h	Mon Jun 09 18:58:39 2008 +0300
@@ -60,7 +60,7 @@
 /*
  * The render_buf for the render_slice_info with the given index value contains
  * the full information for the next row of the render_info render. Returns a
- * bitwise-AND of the SLICE_* flags, or -1 for an error:
+ * bitwise-OR of the SLICE_* flags, or -1 for an error:
  *
  * Valid return values:
  *  zero
@@ -85,7 +85,7 @@
 /*
  * Process a completed row and generate output in the PNG format (how that is
  * handled depends on the render given to render_slices_alloc/init). Returns a
- * bitwise-AND of the SLICE_* flags, or -1 for an error:
+ * bitwise-OR of the SLICE_* flags, or -1 for an error:
  *
  * Valid return values :
  *  zero
@@ -106,6 +106,12 @@
 int render_slices_process_row (struct render_slices *ctx);
 
 /*
+ * Signifiy that the render has been completed. This will flush out buffered
+ * output data.
+ */
+int render_slices_done (struct render_slices *ctx);
+
+/*
  * Free a render_slices. The rendering may or may not be complete.
  */
 void render_slices_free (struct render_slices *ctx);
--- a/render_slices_struct.h	Mon Jun 09 03:15:34 2008 +0300
+++ b/render_slices_struct.h	Mon Jun 09 18:58:39 2008 +0300
@@ -17,16 +17,16 @@
         
         // our offset into rowbuf
         size_t row_offset;
-        
+
         // pointer back to parent
         struct render_slices *self;
     } slices[RENDER_SLICES_MAX];
     
     // how many slices are in use
     size_t num_slices;
-
+    
     // how many slices have reported the current row as done
-    size_t slices_done;
+    size_t segments_done;
 
     // the a pointer to the raw memory buffer
     unsigned char *rowbuf;
--- a/web_main.c	Mon Jun 09 03:15:34 2008 +0300
+++ b/web_main.c	Mon Jun 09 18:58:39 2008 +0300
@@ -17,7 +17,7 @@
 
 #include "common.h"
 #include "http.h"
-#include "render_internal.h"
+#include "render_struct.h"
 #include "render.h"
 #include "remote_node.h"
 #include "remote_pool.h"