render_remote.c
changeset 3 675be0a45157
parent 2 69f8c0acaac7
child 4 49edbdf9ebe7
--- a/render_remote.c	Sat May 31 19:35:21 2008 +0300
+++ b/render_remote.c	Sun Jun 01 01:48:09 2008 +0300
@@ -54,6 +54,7 @@
         perror(desc);                           \
         ctx->cb_fail(ctx->cb_arg);              \
         _remote_render_ctx_free(&ctx);          \
+        return;                                 \
     } while (0)
 
 void _remote_write (struct bufferevent *bev, void *arg) {
@@ -75,7 +76,7 @@
     struct remote_render_ctx *ctx = arg;
     
     // pass the bufferevent's input buffer to our callback - libevent doesn't provide any function to access this, but hopefully this works correctly
-    ctx->cb_data(bev->input, ctx->cb_arg);
+    ctx->cb_data(EVBUFFER_INPUT(bev), ctx->cb_arg);
 }
 
 void _remote_error (struct bufferevent *bev, short what, void *arg) {
@@ -85,6 +86,12 @@
     
     if (what & EVBUFFER_EOF) {
         // great!
+        
+        // send any remaining-chunk data
+        if (EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)) > 0)
+            ctx->cb_data(EVBUFFER_INPUT(bev), ctx->cb_arg);
+
+        // signal completion
         ctx->cb_done(ctx->cb_arg);
 
     } else if (what & EVBUFFER_ERROR) {
@@ -134,7 +141,7 @@
     rrctx->render_cmd.y2 = rctx->y2;
 }
 
-int render_remote (
+struct remote_render_ctx *render_remote (
         render_t *render_ctx,
         struct sockaddr_storage *remote,
         void (*cb_sent)(void *arg),
@@ -148,7 +155,7 @@
 
     if (!ctx) {
         error("render_remote: malloc");
-        return -1;
+        return NULL;
     }
     
     // store the provided callback functions
@@ -167,7 +174,7 @@
     if (sock < 0) {
         free(ctx);
         perror("render_remote: socket");
-        return -1;
+        return NULL;
     }
 
     // mark it as nonblocking
@@ -175,7 +182,7 @@
         free(ctx);
         close(sock);
         perror("render_remote: fcntl");
-        return -1;
+        return NULL;
     }
     
     // initiate the connect
@@ -185,7 +192,7 @@
         free(ctx);
         close(sock);
         perror("render_remote: connect");
-        return -1;
+        return NULL;
     }
 
     // do the libevent dance
@@ -195,9 +202,33 @@
         free(ctx);
         close(sock);
         error("render_remote: event_add");
-        return -1;
+        return NULL;
     }
     
     // success
+    return ctx;
+}
+
+int render_remote_set_chunk_size (struct remote_render_ctx *ctx, size_t chunk_size, size_t overflow_buffer) {
+    if (ctx->data_bev == NULL)
+        return -1;
+
+    bufferevent_setwatermark(ctx->data_bev, EV_READ, chunk_size, chunk_size + overflow_buffer);
+
     return 0;
 }
+
+void render_remote_cancel (struct remote_render_ctx *ctx) {
+    // if it's still just connecting, cancel that
+    if (event_pending(&ctx->ev_conn, EV_WRITE, NULL)) {
+        event_del(&ctx->ev_conn);
+
+    }
+    
+    // close the socket (ctx->ev_conn remains valid even after we're done with it...)
+    close(EVENT_FD(&ctx->ev_conn));
+    
+    // this takes care of the rest
+    _remote_render_ctx_free (&ctx);
+}
+