6 #include "filesystem.h"
10 #include "packagedispatcher.h"
11 #include "preferences.h"
13 #include "renderfarm.h"
14 #include "renderfarmfsserver.h"
16 #include "transportque.h"
19 #include <arpa/inet.h>
23 #include <netinet/in.h>
26 #include <sys/socket.h>
27 #include <sys/types.h>
33 #define _(String) gettext(String)
34 #define gettext_noop(String) String
35 #define N_(String) gettext_noop (String)
38 RenderFarmServer::RenderFarmServer(MWindow *mwindow,
39 PackageDispatcher *packages,
40 Preferences *preferences,
43 int64_t *total_return,
44 Mutex *total_return_lock,
49 this->mwindow = mwindow;
50 this->packages = packages;
51 this->preferences = preferences;
52 this->use_local_rate = use_local_rate;
53 this->result_return = result_return;
54 this->total_return = total_return;
55 this->total_return_lock = total_return_lock;
56 this->default_asset = default_asset;
58 this->brender = brender;
59 client_lock = new Mutex;
62 RenderFarmServer::~RenderFarmServer()
64 clients.remove_all_objects();
68 // Open connections to clients.
69 int RenderFarmServer::start_clients()
73 for(int i = 0; i < preferences->get_enabled_nodes() && !result; i++)
76 RenderFarmServerThread *client = new RenderFarmServerThread(mwindow,
79 clients.append(client);
81 result = client->start_loop();
82 client_lock->unlock();
84 // Fails to connect all without a delay
90 // The render farm must wait for all the clients to finish.
91 int RenderFarmServer::wait_clients()
93 //printf("RenderFarmServer::wait_clients 1\n");
94 clients.remove_all_objects();
95 //printf("RenderFarmServer::wait_clients 2\n");
110 // Waits for requests from every client.
111 // Joins when the client is finished.
112 RenderFarmServerThread::RenderFarmServerThread(MWindow *mwindow,
113 RenderFarmServer *server,
117 this->mwindow = mwindow;
118 this->server = server;
119 this->number = number;
121 frames_per_second = 0;
122 Thread::set_synchronous(1);
127 RenderFarmServerThread::~RenderFarmServerThread()
129 //printf("RenderFarmServerThread::~RenderFarmServerThread 1 %p\n", this);
131 //printf("RenderFarmServerThread::~RenderFarmServerThread 1\n");
132 if(socket_fd >= 0) close(socket_fd);
133 //printf("RenderFarmServerThread::~RenderFarmServerThread 2\n");
137 int RenderFarmServerThread::start_loop()
140 char *hostname = server->preferences->get_node_hostname(number);
141 //printf("RenderFarmServerThread::start_loop 1\n");
143 // Open file for master node
144 if(hostname[0] == '/')
146 if((socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
148 perror(_("RenderFarmServerThread::start_loop: socket\n"));
153 struct sockaddr_un addr;
154 addr.sun_family = AF_FILE;
155 strcpy(addr.sun_path, hostname);
156 int size = (offsetof(struct sockaddr_un, sun_path) +
157 strlen(hostname) + 1);
159 // The master node is always created by BRender. Keep trying for 30 seconds.
161 #define ATTEMPT_DELAY 100000
164 //printf("RenderFarmServerThread::start_loop 2 %s\n", hostname);
167 //printf("RenderFarmServerThread::start_loop 3\n");
168 if(connect(socket_fd, (struct sockaddr*)&addr, size) < 0)
171 if(attempt > 30000000 / ATTEMPT_DELAY)
173 //printf("RenderFarmServerThread::start_loop 4 %s\n", hostname);
174 fprintf(stderr, _("RenderFarmServerThread::start_loop: %s: %s\n"),
180 usleep(ATTEMPT_DELAY);
181 //printf("RenderFarmServerThread::start_loop 5 %s\n", hostname);
185 }while(!result && !done);
186 //printf("RenderFarmServerThread::start_loop 6\n");
192 if((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
194 perror(_("RenderFarmServerThread::start_loop: socket"));
200 struct sockaddr_in addr;
201 struct hostent *hostinfo;
202 addr.sin_family = AF_INET;
203 addr.sin_port = htons(server->preferences->get_node_port(number));
204 hostinfo = gethostbyname(hostname);
207 fprintf(stderr, _("RenderFarmServerThread::start_loop: unknown host %s.\n"),
208 server->preferences->get_node_hostname(number));
213 addr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
215 if(connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
217 fprintf(stderr, _("RenderFarmServerThread::start_loop: %s: %s\n"),
218 server->preferences->get_node_hostname(number),
225 //printf("RenderFarmServerThread::start_loop 7\n");
227 if(!result) Thread::start();
233 int RenderFarmServerThread::read_socket(int socket_fd, char *data, int len, int timeout)
239 //printf("RenderFarmServerThread::read_socket 1\n");
240 while(len > 0 && bytes_read >= 0)
249 FD_SET(socket_fd, &read_fds);
253 result = select(socket_fd + 1,
259 //printf("RenderFarmServerThread::read_socket 1 %d\n", result);
266 bytes_read = read(socket_fd, data + offset, len);
270 offset += bytes_read;
274 //printf("RenderFarmServerThread::read_socket got 0 len=%d\n", len);
280 printf("RenderFarmServerThread::read_socket timed out. len=%d\n", len);
284 //printf("RenderFarmServerThread::read_socket 2\n");
289 int RenderFarmServerThread::write_socket(int socket_fd, char *data, int len, int timeout)
297 FD_SET(socket_fd, &write_fds);
300 //printf("RenderFarmServerThread::write_socket 1\n");
301 result = select(socket_fd + 1,
306 //printf("RenderFarmServerThread::write_socket 2\n");
310 printf("RenderFarmServerThread::write_socket 1 socket timed out. len=%d\n", len);
315 return write(socket_fd, data, len);
318 int RenderFarmServerThread::read_socket(char *data, int len, int timeout)
320 return read_socket(socket_fd, data, len, timeout);
323 int RenderFarmServerThread::write_socket(char *data, int len, int timeout)
325 return write_socket(socket_fd, data, len, timeout);
328 void RenderFarmServerThread::reallocate_buffer(int size)
330 if(buffer && buffer_allocated < size)
338 buffer = new unsigned char[size];
339 buffer_allocated = size;
343 void RenderFarmServerThread::run()
346 unsigned char header[5];
351 buffer_allocated = 0;
352 fs_server = new RenderFarmFSServer(this);
353 fs_server->initialize();
356 // Wait for requests.
357 // Requests consist of request ID's and accompanying buffers.
359 if(read_socket(socket_fd, (char*)header, 5, -1) != 5)
365 int request_id = header[0];
366 int64_t request_size = (((u_int32_t)header[1]) << 24) |
367 (((u_int32_t)header[2]) << 16) |
368 (((u_int32_t)header[3]) << 8) |
369 (u_int32_t)header[4];
371 reallocate_buffer(request_size);
373 // Get accompanying buffer
374 if(read_socket((char*)buffer, request_size, RENDERFARM_TIMEOUT) != request_size)
382 case RENDERFARM_PREFERENCES:
386 case RENDERFARM_ASSET:
394 case RENDERFARM_PACKAGE:
395 send_package(buffer);
398 case RENDERFARM_PROGRESS:
399 set_progress(buffer);
402 case RENDERFARM_SET_RESULT:
406 case RENDERFARM_SET_VMAP:
407 set_video_map(buffer);
410 case RENDERFARM_GET_RESULT:
414 case RENDERFARM_DONE:
420 if(!fs_server->handle_request(request_id, request_size, (char*)buffer))
422 printf(_("RenderFarmServerThread::run: unknown request %02x\n"), request_id);
426 //printf("RenderFarmServerThread::run 4\n");
428 //printf("RenderFarmServerThread::run 5\n");
430 if(buffer) delete [] buffer;
434 int RenderFarmServerThread::write_string(int socket_fd, char *string)
436 unsigned char *datagram;
440 len = strlen(string) + 1;
441 datagram = new unsigned char[len + 4];
443 memcpy(datagram + i, string, len);
444 write_socket(socket_fd, (char*)datagram, len + 4, RENDERFARM_TIMEOUT);
445 //printf("RenderFarmServerThread::write_string %02x%02x%02x%02x\n",
446 // datagram[0], datagram[1], datagram[2], datagram[3]);
451 void RenderFarmServerThread::send_preferences()
456 //printf("RenderFarmServerThread::send_preferences 1\n");
457 server->preferences->save_defaults(&defaults);
458 defaults.save_string(string);
459 //printf("RenderFarmServerThread::send_preferences 2 \n%s\n", string);
460 write_string(socket_fd, string);
465 void RenderFarmServerThread::send_asset()
468 //printf("RenderFarmServerThread::send_asset 1\n");
470 server->default_asset->write(mwindow->plugindb,
474 file.terminate_string();
476 //printf("RenderFarmServerThread::send_asset 2\n");
477 write_string(socket_fd, file.string);
478 //printf("RenderFarmServerThread::send_asset 3\n");
482 void RenderFarmServerThread::send_edl()
487 server->edl->save_xml(mwindow->plugindb,
492 file.terminate_string();
493 //printf("RenderFarmServerThread::send_edl\n%s\n\n", file.string);
495 write_string(socket_fd, file.string);
496 //printf("RenderFarmServerThread::send_edl 2\n");
500 void RenderFarmServerThread::send_package(unsigned char *buffer)
502 this->frames_per_second = (double)((((u_int32_t)buffer[0]) << 24) |
503 (((u_int32_t)buffer[1]) << 16) |
504 (((u_int32_t)buffer[2]) << 8) |
505 ((u_int32_t)buffer[3])) /
508 //printf("RenderFarmServerThread::send_package 1\n");
509 RenderPackage *package =
510 server->packages->get_package(frames_per_second,
512 server->use_local_rate);
514 //printf("RenderFarmServerThread::send_package 2\n");
516 char datagram[BCTEXTLEN];
521 datagram[0] = datagram[1] = datagram[2] = datagram[3] = 0;
522 write_socket(datagram, 4, RENDERFARM_TIMEOUT);
528 strcpy(&datagram[i], package->path);
529 i += strlen(package->path);
532 STORE_INT32(package->audio_start);
533 STORE_INT32(package->audio_end);
534 STORE_INT32(package->video_start);
535 STORE_INT32(package->video_end);
536 int use_brender = (server->brender ? 1 : 0);
537 STORE_INT32(use_brender);
541 STORE_INT32(len - 4);
543 write_socket(datagram, len, RENDERFARM_TIMEOUT);
548 void RenderFarmServerThread::set_progress(unsigned char *buffer)
550 server->total_return_lock->lock();
551 *server->total_return += (int64_t)(((u_int32_t)buffer[0]) << 24) |
552 (((u_int32_t)buffer[1]) << 16) |
553 (((u_int32_t)buffer[2]) << 8) |
554 ((u_int32_t)buffer[3]);
555 server->total_return_lock->unlock();
558 void RenderFarmServerThread::set_video_map(unsigned char *buffer)
561 server->brender->set_video_map((int64_t)(((u_int32_t)buffer[0]) << 24) |
562 (((u_int32_t)buffer[1]) << 16) |
563 (((u_int32_t)buffer[2]) << 8) |
564 ((u_int32_t)buffer[3]),
565 (int64_t)(((u_int32_t)buffer[4]) << 24) |
566 (((u_int32_t)buffer[5]) << 16) |
567 (((u_int32_t)buffer[6]) << 8) |
568 ((u_int32_t)buffer[7]));
572 void RenderFarmServerThread::set_result(unsigned char *buffer)
574 //printf("RenderFarmServerThread::set_result %p\n", buffer);
575 if(!*server->result_return)
576 *server->result_return = buffer[0];
580 void RenderFarmServerThread::get_result()
582 unsigned char data[1];
583 data[0] = *server->result_return;
584 write_socket((char*)data, 1, RENDERFARM_TIMEOUT);