render_node.c
changeset 12 43297144f196
parent 11 082bfaf38cf0
child 13 ee426f453cf5
equal deleted inserted replaced
11:082bfaf38cf0 12:43297144f196
     1 #include <stdio.h>
       
     2 #include <sys/types.h>
       
     3 #include <arpa/inet.h>
       
     4 #include <sys/socket.h>
       
     5 #include <stdlib.h>
       
     6 #include <signal.h>
       
     7 #include <string.h>
       
     8 #include <unistd.h>
       
     9 
       
    10 #include "common.h"
       
    11 #include "render.h"
       
    12 #include "render_remote.h"
       
    13 #include "render_local.h"
       
    14 #include "mandelbrot.h"
       
    15 
       
    16 void sigpipe_handler (int signal) {
       
    17     /* ignore */
       
    18     fprintf(stderr, "SIGPIPE\n");
       
    19 }
       
    20 
       
    21 void sigpipe_ignore () {
       
    22     struct sigaction sigpipe_action;
       
    23 
       
    24     memset(&sigpipe_action, 0, sizeof(sigpipe_action));
       
    25     sigpipe_action.sa_handler = SIG_IGN;
       
    26 
       
    27     if (sigaction(SIGPIPE, &sigpipe_action, NULL))
       
    28         perr_exit("sigaction");
       
    29 }
       
    30 
       
    31 int my_fread(FILE *fh, void *ptr, size_t size) {
       
    32     int ret = fread(ptr, size, 1, fh);
       
    33     
       
    34     if (ret == 0) {
       
    35         error("EOF");
       
    36         return 0;
       
    37 
       
    38     } else if (ret != 1) {
       
    39         perror("fread");
       
    40         return 0;
       
    41     }
       
    42 
       
    43     return 1;
       
    44 }
       
    45 
       
    46 int read_byte (FILE *fh, u_int8_t *byte) {
       
    47     return my_fread(fh, byte, sizeof(*byte));
       
    48 }
       
    49 
       
    50 int read_int (FILE *fh, u_int32_t *i) {
       
    51     if (!my_fread(fh, i, sizeof(*i)))
       
    52         return 0;
       
    53 
       
    54     *i = ntohl(*i);
       
    55 
       
    56     return 1;
       
    57 }
       
    58 
       
    59 int read_double (FILE *fh, double *dbl) {
       
    60     if (!my_fread(fh, dbl, sizeof(*dbl)))
       
    61         return 0;
       
    62 
       
    63     return 1;
       
    64 }
       
    65 
       
    66 void handle_client (int sock) {
       
    67     double duration;
       
    68     struct render *ctx;
       
    69     FILE *fh;
       
    70     u_int8_t mode;
       
    71     u_int32_t img_w, img_h;
       
    72     double x1, y1, x2, y2;
       
    73 
       
    74     
       
    75     // open it as a FILE*
       
    76     if (!(fh = fdopen(sock, "r+")))
       
    77         ERROR("fdopen");
       
    78     
       
    79     // read the parameters
       
    80     if (
       
    81             !read_byte(fh, &mode)
       
    82          || !read_int(fh, &img_w)
       
    83          || !read_int(fh, &img_h)
       
    84          || !read_double(fh, &x1)
       
    85          || !read_double(fh, &y1)
       
    86          || !read_double(fh, &x2)
       
    87          || !read_double(fh, &y2)
       
    88     )
       
    89         ERROR("read_{byte,int,double}");
       
    90 
       
    91     printf("RENDER: [%ux%u] (%f, %f) -> (%f, %f): ... ", img_w, img_h, x1, y1, x2, y2);
       
    92     fflush(stdout);
       
    93 
       
    94     // set up the render_ctx
       
    95     if (!(ctx = render_alloc()))
       
    96         ERROR("render_alloc");
       
    97 
       
    98     if (render_set_mode(ctx, mode))
       
    99         ERROR("render_set_mode");
       
   100 
       
   101     if (render_set_size(ctx, img_w, img_h))
       
   102         ERROR("render_set_size");
       
   103 
       
   104     if (render_region_raw(ctx, x1, y1, x2, y2))
       
   105         ERROR("render_region_raw");
       
   106 
       
   107     if (render_io_stream(ctx, fh))
       
   108         ERROR("render_io_stream");
       
   109   
       
   110     
       
   111     // render!
       
   112     if (render_local(ctx, &duration))
       
   113         ERROR("render_local");
       
   114 
       
   115     printf("time=%fs\n", duration);
       
   116 
       
   117 error:
       
   118     // close the FILE* and socket
       
   119     fclose(fh);
       
   120     
       
   121     return;
       
   122 }
       
   123 
       
   124 
       
   125 int main (int argc, char** argv) {
       
   126     int ssock, sock;
       
   127     struct sockaddr_in addr;
       
   128     socklen_t addr_len;
       
   129     
       
   130     // parse arguments
       
   131     int opt;
       
   132     const char *port_name = NULL;
       
   133     unsigned short port;
       
   134 
       
   135     while ((opt = getopt(argc, argv, "l:")) != -1) {
       
   136         switch (opt) {
       
   137             case 'l':
       
   138                 if (port_name)
       
   139                     ERROR("only specify -l once");
       
   140 
       
   141                 port_name = optarg;
       
   142                 break;
       
   143 
       
   144             default:
       
   145                 err_exit("Usage: %s [-l port]", argv[0]);
       
   146         }
       
   147     }
       
   148     
       
   149     // post-process arguments
       
   150     if (!port_name)
       
   151         port_name = RENDER_PORT_NAME;
       
   152 
       
   153     if (!(port = atoi(port_name)))
       
   154         ERROR_FMT("invalid port: %s", port_name);
       
   155 
       
   156     // create the socket
       
   157     if ((ssock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
       
   158         PERROR("socket");
       
   159 
       
   160     addr.sin_family = AF_INET;
       
   161     addr.sin_port = htons(port);
       
   162     addr.sin_addr.s_addr = INADDR_ANY;
       
   163 
       
   164     if (bind(ssock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1)
       
   165         PERROR("bind");
       
   166     
       
   167     if (listen(ssock, 1) == -1)
       
   168         PERROR("listen");
       
   169     
       
   170     // ignore sigpipe
       
   171     sigpipe_ignore();
       
   172     
       
   173     // main accept loop
       
   174     printf("RUN: %s:%hu\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
       
   175 
       
   176     while (1) {
       
   177         addr_len = sizeof(struct sockaddr_in);
       
   178 
       
   179         // accept a new client
       
   180         if ((sock = accept(ssock, (struct sockaddr *) &addr, &addr_len)) == -1)
       
   181             PERROR("accept");
       
   182         
       
   183         printf("ACCEPT: %s:%hu\n", inet_ntoa(addr.sin_addr), addr.sin_port);
       
   184         
       
   185         // handle their resquest
       
   186         handle_client(sock);
       
   187     }
       
   188 
       
   189 error:
       
   190     return 1;
       
   191 }
       
   192