source: subversion/applications/utils/mod_tile/render_old.c @ 15816

Last change on this file since 15816 was 13126, checked in by jonb, 11 years ago

Applied MacOSX compile fixes from Artem with a few modifications

File size: 8.6 KB
Line 
1#define _GNU_SOURCE
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <sys/stat.h>
9#include <sys/time.h>
10#include <sys/un.h>
11#include <poll.h>
12#include <errno.h>
13#include <math.h>
14#include <getopt.h>
15#include <time.h>
16#include <sys/types.h>
17#include <dirent.h>
18#include <limits.h>
19#include <string.h>
20
21#include "gen_tile.h"
22#include "protocol.h"
23#include "render_config.h"
24#include "dir_utils.h"
25
26#ifndef METATILE
27#warning("render_old not implemented for non-metatile mode. Feel free to submit fix")
28int main(int argc, char **argv)
29{
30    fprintf(stderr, "render_old not implemented for non-metatile mode. Feel free to submit fix!\n");
31    return -1;
32}
33#else
34
35#define INILINE_MAX 256
36static int minZoom = 0;
37static int maxZoom = 18;
38static int verbose = 0;
39static int num_render = 0, num_all = 0;
40static time_t planetTime;
41static struct timeval start, end;
42
43
44void display_rate(struct timeval start, struct timeval end, int num) 
45{
46    int d_s, d_us;
47    float sec;
48
49    d_s  = end.tv_sec  - start.tv_sec;
50    d_us = end.tv_usec - start.tv_usec;
51
52    sec = d_s + d_us / 1000000.0;
53
54    printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
55    fflush(NULL);
56}
57
58static time_t getPlanetTime(void)
59{
60    static time_t last_check;
61    static time_t planet_timestamp;
62    time_t now = time(NULL);
63    struct stat buf;
64
65    // Only check for updates periodically
66    if (now < last_check + 300)
67        return planet_timestamp;
68
69    last_check = now;
70    if (stat(PLANET_TIMESTAMP, &buf)) {
71        printf("Planet timestamp file " PLANET_TIMESTAMP " is missing");
72        // Make something up
73        planet_timestamp = now - 3 * 24 * 60 * 60;
74    } else {
75        if (buf.st_mtime != planet_timestamp) {
76            printf("Planet file updated at %s", ctime(&buf.st_mtime));
77            planet_timestamp = buf.st_mtime;
78        }
79    }
80    return planet_timestamp;
81}
82
83int get_load_avg(void)
84{
85    FILE *loadavg = fopen("/proc/loadavg", "r");
86    int avg = 1000;
87
88    if (!loadavg) {
89        fprintf(stderr, "failed to read /proc/loadavg");
90        return 1000;
91    }
92    if (fscanf(loadavg, "%d", &avg) != 1) {
93        fprintf(stderr, "failed to parse /proc/loadavg");
94        fclose(loadavg);
95        return 1000;
96    }
97    fclose(loadavg);
98
99    return avg;
100}
101
102
103int process_loop(int fd, char * xmlname, int x, int y, int z)
104{
105    struct protocol cmd, rsp;
106    //struct pollfd fds[1];
107    int ret = 0;
108
109    bzero(&cmd, sizeof(cmd));
110
111    cmd.ver = 2;
112    cmd.cmd = cmdRender;
113    cmd.z = z;
114    cmd.x = x;
115    cmd.y = y;
116    strcpy(cmd.xmlname, xmlname);
117    //strcpy(cmd.path, "/tmp/foo.png");
118    //printf("Sending request\n");
119    ret = send(fd, &cmd, sizeof(cmd), 0);
120    if (ret != sizeof(cmd)) {
121        perror("send error");
122    }
123        //printf("Waiting for response\n");
124    bzero(&rsp, sizeof(rsp));
125    ret = recv(fd, &rsp, sizeof(rsp), 0);
126    if (ret != sizeof(rsp)) {
127        perror("recv error");
128        return 0;
129    }
130        //printf("Got response\n");
131
132    if (rsp.cmd != cmdDone) {
133        printf("rendering failed, pausing\n");
134        sleep(10);
135    }
136
137    if (!ret)
138        perror("Socket send error");
139    return ret;
140}
141
142void process(int fd, const char *name)
143{
144    struct stat s;
145    char xmlconfig[XMLCONFIG_MAX];
146    int x, y, z;
147
148    if (path_to_xyz(name, xmlconfig, &x, &y, &z))
149        return;
150
151    num_all++;
152
153//    printf("Found xml(%s) x(%d) y(%d) z(%d)\n", xmlconfig, x, y, z);
154    if ((stat(name, &s) < 0) || (planetTime > s.st_mtime)) {
155         // missing or old, render it
156        printf("Requesting xml(%s) x(%d) y(%d) z(%d)\n", xmlconfig, x, y, z);
157        process_loop(fd, xmlconfig, x, y, z);
158        num_render++;
159        if (!(num_render % 10)) {
160            gettimeofday(&end, NULL);
161            printf("\n");
162            printf("Meta tiles rendered: ");
163            display_rate(start, end, num_render);
164            printf("Total tiles rendered: ");
165            display_rate(start, end, num_render * METATILE * METATILE);
166            printf("Total tiles handled from input: ");
167            display_rate(start, end, num_all);
168        }
169    }
170}
171
172static void check_load(void)
173{
174    int avg = get_load_avg();
175
176    while (avg >= MAX_LOAD_OLD) {
177        printf("Load average %d, sleeping\n", avg);
178        sleep(5);
179        avg = get_load_avg();
180    }
181}
182
183static void descend(int fd, const char *search)
184{
185    DIR *tiles = opendir(search);
186    struct dirent *entry;
187    char path[PATH_MAX];
188
189    if (!tiles) {
190        fprintf(stderr, "Unable to open directory: %s\n", search);
191        return;
192    }
193
194    while ((entry = readdir(tiles))) {
195        struct stat b;
196        char *p;
197
198        check_load();
199
200        if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
201            continue;
202        snprintf(path, sizeof(path), "%s/%s", search, entry->d_name);
203        if (stat(path, &b))
204            continue;
205        if (S_ISDIR(b.st_mode)) {
206            descend(fd, path);
207            continue;
208        }
209        p = strrchr(path, '.');
210        if (p && !strcmp(p, ".meta")) {
211//            printf("Found tile %s\n", path);
212            process(fd, path);
213        }
214    }
215    closedir(tiles);
216}
217
218
219int main(int argc, char **argv)
220{
221    const char *spath = RENDER_SOCKET;
222    int fd;
223    struct sockaddr_un addr;
224    int z, c;
225
226    while (1) {
227        int option_index = 0;
228        static struct option long_options[] = {
229            {"min-zoom", 1, 0, 'z'},
230            {"max-zoom", 1, 0, 'Z'},
231            {"verbose", 0, 0, 'v'},
232            {"help", 0, 0, 'h'},
233            {0, 0, 0, 0}
234        };
235
236        c = getopt_long(argc, argv, "hvz:Z:", long_options, &option_index);
237        if (c == -1)
238            break;
239
240        switch (c) {
241            case 'z':
242                minZoom=atoi(optarg);
243                if (minZoom < 0 || minZoom > 18) {
244                    fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and 18\n");
245                    return 1;
246                }
247                break;
248            case 'Z':
249                maxZoom=atoi(optarg);
250                if (maxZoom < 0 || maxZoom > 18) {
251                    fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and 18\n");
252                    return 1;
253                }
254                break;
255            case 'v':
256                verbose=1;
257                break;
258            case 'h':
259                fprintf(stderr, "Search the rendered tiles and re-render tiles which are older then the last planet import\n");
260                fprintf(stderr, "\t-z|--min-zoom\tonly render tiles greater or equal this zoom level (default 0)\n");
261                fprintf(stderr, "\t-Z|--max-zoom\tonly render tiles less than or equal to this zoom level (default 18)\n");
262                return -1;
263            default:
264                fprintf(stderr, "unhandled char '%c'\n", c);
265                break;
266        }
267    }
268
269    if (maxZoom < minZoom) {
270        fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
271        return 1;
272    }
273
274    fprintf(stderr, "Rendering old tiles\n");
275
276    planetTime = getPlanetTime();
277
278    fd = socket(PF_UNIX, SOCK_STREAM, 0);
279    if (fd < 0) {
280        fprintf(stderr, "failed to create unix socket\n");
281        exit(2);
282    }
283
284    bzero(&addr, sizeof(addr));
285    addr.sun_family = AF_UNIX;
286    strncpy(addr.sun_path, spath, sizeof(addr.sun_path));
287
288    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
289        fprintf(stderr, "socket connect failed for: %s\n", spath);
290        close(fd);
291        exit(3);
292    }
293
294    gettimeofday(&start, NULL);
295
296    FILE * hini ;
297    char line[INILINE_MAX];
298    char value[INILINE_MAX];
299
300    // Load the config
301    if ((hini=fopen(RENDERD_CONFIG, "r"))==NULL) {
302        fprintf(stderr, "Config: cannot open %s\n", RENDERD_CONFIG);
303        exit(7);
304    }
305
306    while (fgets(line, INILINE_MAX, hini)!=NULL) {
307        if (line[0] == '[') {
308            if (strlen(line) >= XMLCONFIG_MAX){
309                fprintf(stderr, "XML name too long: %s\n", line);
310                exit(7);
311            }
312            sscanf(line, "[%[^]]", value);
313
314            for (z=minZoom; z<=maxZoom; z++) {
315                char path[PATH_MAX];
316                snprintf(path, PATH_MAX, HASH_PATH "/%s/%d", value, z);
317                descend(fd, path);
318            }
319        }
320    }
321
322    gettimeofday(&end, NULL);
323    printf("\nTotal for all tiles rendered\n");
324    printf("Meta tiles rendered: ");
325    display_rate(start, end, num_render);
326    printf("Total tiles rendered: ");
327    display_rate(start, end, num_render * METATILE * METATILE);
328    printf("Total tiles handled: ");
329    display_rate(start, end, num_all);
330
331    close(fd);
332    return 0;
333}
334#endif
Note: See TracBrowser for help on using the repository browser.