render_remote.c
author Tero Marttila <terom@fixme.fi>
Sun, 01 Jun 2008 01:48:09 +0300
changeset 3 675be0a45157
parent 2 69f8c0acaac7
child 4 49edbdf9ebe7
permissions -rw-r--r--
working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.

committer: Tero Marttila <terom@fixme.fi>
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include <stdlib.h>
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include <arpa/inet.h>
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include <unistd.h>
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
#include <fcntl.h>
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <errno.h>
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include "render_remote.h"
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include "common.h"
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
struct remote_render_ctx {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
    struct event ev_conn;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    struct bufferevent *data_bev;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    #pragma pack(push)
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
    #pragma pack(1)
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
    struct {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
        u_int8_t    mode;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
        u_int32_t   img_w;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
        u_int32_t   img_h;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
        double      x1;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
        double      y1;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
        double      x2;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
        double      y2;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    } render_cmd;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
    #pragma pack(pop)
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
    void (*cb_sent)(void *arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
    void (*cb_data)(struct evbuffer *buf, void *arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
    void (*cb_done)(void *arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
    void (*cb_fail)(void *arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    void *cb_arg;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
};
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
void _remote_render_ctx_free (struct remote_render_ctx **ctx) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
    // free the data_bev
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
    if ((*ctx)->data_bev) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
        bufferevent_free((*ctx)->data_bev);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
        (*ctx)->data_bev = NULL;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
    // free the context structure
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    free(*ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    *ctx = NULL;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
}
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
#define RENDER_FAILED(ctx, desc) \
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    do {                                        \
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
        perror(desc);                           \
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
        ctx->cb_fail(ctx->cb_arg);              \
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
        _remote_render_ctx_free(&ctx);          \
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    57
        return;                                 \
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
    } while (0)
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
void _remote_write (struct bufferevent *bev, void *arg) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    struct remote_render_ctx *ctx = arg;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
    // the write buffer was drained, so the render command was sent
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
    ctx->cb_sent(ctx->cb_arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    // we don't care about EV_WRITE anymore
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
    if (bufferevent_disable(ctx->data_bev, EV_WRITE))
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
        RENDER_FAILED(ctx, "render_remote: bufferevent_disable");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    // start receiving data
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
    if (bufferevent_enable(ctx->data_bev, EV_READ))
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
        RENDER_FAILED(ctx, "render_remote: bufferevent_enable");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
}
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
void _remote_read (struct bufferevent *bev, void *arg) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
    struct remote_render_ctx *ctx = arg;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    // pass the bufferevent's input buffer to our callback - libevent doesn't provide any function to access this, but hopefully this works correctly
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    79
    ctx->cb_data(EVBUFFER_INPUT(bev), ctx->cb_arg);
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
}
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
void _remote_error (struct bufferevent *bev, short what, void *arg) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    struct remote_render_ctx *ctx = arg;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
    // OH NOES; WHAT DO WE DO!?
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
    if (what & EVBUFFER_EOF) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        // great!
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    89
        
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    90
        // send any remaining-chunk data
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    91
        if (EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)) > 0)
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    92
            ctx->cb_data(EVBUFFER_INPUT(bev), ctx->cb_arg);
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    93
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    94
        // signal completion
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
        ctx->cb_done(ctx->cb_arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
    } else if (what & EVBUFFER_ERROR) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
        // crap.
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
        perr("render_remote");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
        ctx->cb_fail(ctx->cb_arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    } else if (what & EVBUFFER_TIMEOUT) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
        // ah well
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        error("render_remote: timeout");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
        ctx->cb_fail(ctx->cb_arg);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
    } else {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
        err_exit("weird bufferevent error code: 0x%02X", what);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
    // free resources
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
    _remote_render_ctx_free(&ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
}
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
void _remote_connected (int fd, short event, void *arg) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
    struct remote_render_ctx *ctx = arg;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
    // set up the read/write bufferevent
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    if ((ctx->data_bev = bufferevent_new(fd, &_remote_read, &_remote_write, &_remote_error, ctx)) == NULL)
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
        RENDER_FAILED(ctx, "render_remote: bufferevent_new");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
    // write the render command
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    if (bufferevent_write(ctx->data_bev, &ctx->render_cmd, sizeof(ctx->render_cmd)))
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
        RENDER_FAILED(ctx, "render_remote: bufferevent_write");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
    // wait for it to be written out
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
    if (bufferevent_enable(ctx->data_bev, EV_WRITE))
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
        RENDER_FAILED(ctx, "render_remote: bufferevent_enable");
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
}
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
void render_cmd_build (render_t *rctx, struct remote_render_ctx *rrctx) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    // just copy over the render params to the render_cmd
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
    rrctx->render_cmd.mode = rctx->mode;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    rrctx->render_cmd.img_w = htonl(rctx->img_w);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
    rrctx->render_cmd.img_h = htonl(rctx->img_h);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
    rrctx->render_cmd.x1 = rctx->x1;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
    rrctx->render_cmd.y1 = rctx->y1;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
    rrctx->render_cmd.x2 = rctx->x2;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
    rrctx->render_cmd.y2 = rctx->y2;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
}
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   144
struct remote_render_ctx *render_remote (
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
        render_t *render_ctx,
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
        struct sockaddr_storage *remote,
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        void (*cb_sent)(void *arg),
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
        void (*cb_data)(struct evbuffer *buf, void *arg),
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        void (*cb_done)(void *arg),
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
        void (*cb_fail)(void *arg),
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
        void *cb_arg
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
) {    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
    // alloc the remote render ctx
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
    struct remote_render_ctx *ctx = malloc(sizeof(struct remote_render_ctx));
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
    if (!ctx) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
        error("render_remote: malloc");
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   158
        return NULL;
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
    // store the provided callback functions
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    ctx->cb_sent = cb_sent;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    ctx->cb_data = cb_data;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
    ctx->cb_done = cb_done;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
    ctx->cb_fail = cb_fail;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
    ctx->cb_arg = cb_arg;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
    // copy the relevant stuff from the render_ctx
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
    render_cmd_build(render_ctx, ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    // create the socket
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
    int sock = socket(remote->ss_family, SOCK_STREAM, 0);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    if (sock < 0) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        free(ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        perror("render_remote: socket");
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   177
        return NULL;
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    // mark it as nonblocking
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
    if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
        free(ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
        close(sock);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
        perror("render_remote: fcntl");
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   185
        return NULL;
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
    // initiate the connect
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    int err = connect(sock, (struct sockaddr *) remote, sizeof(*remote));
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    if (err != -1 || errno != EINPROGRESS) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        free(ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
        close(sock);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
        perror("render_remote: connect");
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   195
        return NULL;
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
    // do the libevent dance
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
    event_set(&ctx->ev_conn, sock, EV_WRITE, &_remote_connected, ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
    if (event_add(&ctx->ev_conn, NULL)) {
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
        free(ctx);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
        close(sock);
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
        error("render_remote: event_add");
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   205
        return NULL;
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
    }
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
    
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    // success
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   209
    return ctx;
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   210
}
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   211
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   212
int render_remote_set_chunk_size (struct remote_render_ctx *ctx, size_t chunk_size, size_t overflow_buffer) {
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   213
    if (ctx->data_bev == NULL)
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   214
        return -1;
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   215
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   216
    bufferevent_setwatermark(ctx->data_bev, EV_READ, chunk_size, chunk_size + overflow_buffer);
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   217
2
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
    return 0;
69f8c0acaac7 working web_main that uses render_remote
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
}
3
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   220
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   221
void render_remote_cancel (struct remote_render_ctx *ctx) {
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   222
    // if it's still just connecting, cancel that
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   223
    if (event_pending(&ctx->ev_conn, EV_WRITE, NULL)) {
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   224
        event_del(&ctx->ev_conn);
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   225
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   226
    }
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   227
    
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   228
    // close the socket (ctx->ev_conn remains valid even after we're done with it...)
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   229
    close(EVENT_FD(&ctx->ev_conn));
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   230
    
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   231
    // this takes care of the rest
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   232
    _remote_render_ctx_free (&ctx);
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   233
}
675be0a45157 working chunked-streaming of remote-rendered mandelbrots in web_main, next step will be flow control. Remote rendering doesn't compile in render_node.
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   234