--- 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"