4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "filesystem.h"
33 #include "pluginserver.h"
34 #include "preferences.h"
35 #include "renderfarm.h"
36 #include "renderfarmclient.h"
37 //#include "renderfarmfsclient.h"
38 #include "sighandler.h"
40 #include <arpa/inet.h>
44 #include <netinet/in.h>
47 #include <sys/socket.h>
48 #include <sys/types.h>
56 // The render client waits for connections from the server.
57 // Then it starts a thread for each connection.
58 RenderFarmClient::RenderFarmClient(int port,
64 this->deamon_path = deamon_path;
65 SigHandler *signals = new SigHandler;
66 signals->initialize();
69 (void)nice(nice_value);
72 MWindow::init_defaults(boot_defaults, config_path);
73 boot_preferences = new Preferences;
74 boot_preferences->load_defaults(boot_defaults);
75 MWindow::init_plugins(0, boot_preferences);
81 RenderFarmClient::~RenderFarmClient()
85 delete boot_preferences;
86 plugindb->remove_all_objects();
91 void RenderFarmClient::main_loop()
94 BC_WindowBase::get_resources()->vframe_shm = 1;
97 // Open listening port
101 struct sockaddr_in addr;
103 addr.sin_family = AF_INET;
104 addr.sin_port = htons((unsigned short)port);
105 addr.sin_addr.s_addr = htonl(INADDR_ANY);
107 if((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
109 perror(_("RenderFarmClient::main_loop: socket"));
114 (struct sockaddr*)&addr,
118 _("RenderFarmClient::main_loop: bind port %d: %s"),
126 struct sockaddr_un addr;
127 addr.sun_family = AF_FILE;
128 strcpy(addr.sun_path, deamon_path);
129 int size = (offsetof(struct sockaddr_un, sun_path) +
130 strlen(deamon_path) + 1);
132 if((socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
134 perror(_("RenderFarmClient::main_loop: socket"));
139 (struct sockaddr*)&addr,
143 _("RenderFarmClient::main_loop: bind path %s: %s\n"),
150 // Wait for connections
151 printf("RenderFarmClient::main_loop: client started\n");
154 if(listen(socket_fd, 256) < 0)
156 perror(_("RenderFarmClient::main_loop: listen"));
166 struct sockaddr_in clientname;
167 socklen_t size = sizeof(clientname);
168 if((new_socket_fd = accept(socket_fd,
169 (struct sockaddr*)&clientname,
172 perror(_("RenderFarmClient::main_loop: accept"));
177 printf("RenderFarmClient::main_loop: Session started from %s\n", inet_ntoa(clientname.sin_addr));
178 RenderFarmClientThread *thread =
179 new RenderFarmClientThread(this);
180 thread->main_loop(new_socket_fd);
185 struct sockaddr_un clientname;
186 socklen_t size = sizeof(clientname);
187 if((new_socket_fd = accept(socket_fd,
188 (struct sockaddr*)&clientname,
191 perror(_("RenderFarmClient::main_loop: accept"));
196 printf("RenderFarmClient::main_loop: Session started from %s\n", clientname.sun_path);
197 RenderFarmClientThread *thread =
198 new RenderFarmClientThread(this);
199 thread->main_loop(new_socket_fd);
205 void RenderFarmClient::kill_client()
207 printf("RenderFarmClient::kill_client 1\n");
210 printf("RenderFarmClient::kill_client 2\n");
212 kill(this_pid, SIGKILL);
226 // The thread requests jobs from the server until the job table is empty
227 // or the server reports an error. This thread must poll the server
228 // after every frame for the error status.
229 // Detaches when finished.
230 RenderFarmClientThread::RenderFarmClientThread(RenderFarmClient *client)
233 this->client = client;
234 frames_per_second = 0;
235 Thread::set_synchronous(0);
237 mutex_lock = new Mutex("RenderFarmClientThread::mutex_lock");
242 RenderFarmClientThread::~RenderFarmClientThread()
244 // if(fs_client) delete fs_client;
251 int RenderFarmClientThread::send_request_header(int request,
254 unsigned char datagram[5];
255 datagram[0] = request;
259 // printf("RenderFarmClientThread::send_request_header %d %02x%02x%02x%02x%02x\n",
260 // request, datagram[0], datagram[1], datagram[2], datagram[3], datagram[4]);
262 return (write_socket((char*)datagram, 5) != 5);
265 int RenderFarmClientThread::write_socket(char *data, int len)
267 //printf("RenderFarmClientThread::write_socket 1\n");
268 int result = write(socket_fd, data, len);
269 //printf("RenderFarmClientThread::write_socket 10\n");
273 int RenderFarmClientThread::read_socket(char *data, int len)
277 //printf("RenderFarmClientThread::read_socket 1\n");
278 watchdog->begin_request();
279 while(len > 0 && bytes_read >= 0)
281 bytes_read = read(socket_fd, data + offset, len);
285 offset += bytes_read;
293 watchdog->end_request();
294 //printf("RenderFarmClientThread::read_socket 10\n");
299 int RenderFarmClientThread::write_int64(int64_t value)
301 unsigned char data[sizeof(int64_t)];
302 data[0] = (value >> 56) & 0xff;
303 data[1] = (value >> 48) & 0xff;
304 data[2] = (value >> 40) & 0xff;
305 data[3] = (value >> 32) & 0xff;
306 data[4] = (value >> 24) & 0xff;
307 data[5] = (value >> 16) & 0xff;
308 data[6] = (value >> 8) & 0xff;
309 data[7] = value & 0xff;
310 return (write_socket((char*)data, sizeof(int64_t)) != sizeof(int64_t));
313 int64_t RenderFarmClientThread::read_int64(int *error)
316 if(!error) error = &temp;
318 unsigned char data[sizeof(int64_t)];
319 *error = (read_socket((char*)data, sizeof(int64_t)) != sizeof(int64_t));
321 // Make it return 1 if error so it can be used to read a result code from the
326 result = (((int64_t)data[0]) << 56) |
327 (((uint64_t)data[1]) << 48) |
328 (((uint64_t)data[2]) << 40) |
329 (((uint64_t)data[3]) << 32) |
330 (((uint64_t)data[4]) << 24) |
331 (((uint64_t)data[5]) << 16) |
332 (((uint64_t)data[6]) << 8) |
338 void RenderFarmClientThread::read_string(char* &string)
340 unsigned char header[4];
341 if(read_socket((char*)header, 4) != 4)
347 int64_t len = (((u_int32_t)header[0]) << 24) |
348 (((u_int32_t)header[1]) << 16) |
349 (((u_int32_t)header[2]) << 8) |
350 ((u_int32_t)header[3]);
354 string = new char[len];
355 if(read_socket(string, len) != len)
366 void RenderFarmClientThread::abort()
368 send_completion(socket_fd);
373 void RenderFarmClientThread::lock(const char *location)
375 mutex_lock->lock(location);
378 void RenderFarmClientThread::unlock()
380 mutex_lock->unlock();
383 void RenderFarmClientThread::get_command(int socket_fd, int *command)
386 *command = read_int64(&error);
395 void RenderFarmClientThread::read_preferences(int socket_fd,
396 Preferences *preferences)
398 lock("RenderFarmClientThread::read_preferences");
399 send_request_header(RENDERFARM_PREFERENCES,
406 defaults.load_string((char*)string);
407 preferences->load_defaults(&defaults);
415 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
417 lock("RenderFarmClientThread::read_asset");
418 send_request_header(RENDERFARM_ASSET,
423 read_string(string1);
424 read_string(string2);
429 file.read_from_string((char*)string2);
435 defaults.load_string((char*)string1);
436 asset->load_defaults(&defaults,
444 //printf("RenderFarmClientThread::read_asset %d\n", __LINE__);
452 void RenderFarmClientThread::read_edl(int socket_fd,
454 Preferences *preferences)
456 lock("RenderFarmClientThread::read_edl");
457 send_request_header(RENDERFARM_EDL,
465 file.read_from_string((char*)string);
482 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
484 lock("RenderFarmClientThread::read_package");
485 send_request_header(RENDERFARM_PACKAGE,
488 unsigned char datagram[5];
492 // Fails if -ieee isn't set.
493 int64_t fixed = !EQUIV(frames_per_second, 0.0) ?
494 (int64_t)(frames_per_second * 65536.0) : 0;
496 write_socket((char*)datagram, 4);
499 //printf("RenderFarmClientThread::read_package 1 %f %ld\n", frames_per_second, fixed);
501 unsigned char *data_ptr;
503 //printf("RenderFarmClientThread::read_package 2 %p\n", data);
504 // Signifies end of session.
507 // printf(_("RenderFarmClientThread::read_package no output path recieved.\n"));
512 //printf("RenderFarmClientThread::read_package 2\n");
515 data_ptr = (unsigned char*)data;
516 strcpy(package->path, data);
517 data_ptr += strlen(package->path);
519 package->audio_start = READ_INT32(data_ptr);
521 package->audio_end = READ_INT32(data_ptr);
523 package->video_start = READ_INT32(data_ptr);
525 package->video_end = READ_INT32(data_ptr);
527 package->use_brender = READ_INT32(data_ptr);
535 int RenderFarmClientThread::send_completion(int socket_fd)
537 lock("RenderFarmClientThread::send_completion");
538 int result = send_request_header(RENDERFARM_DONE, 0);
544 void RenderFarmClientThread::ping_server()
546 lock("RenderFarmClientThread::ping_server");
547 send_request_header(RENDERFARM_KEEPALIVE, 0);
553 void RenderFarmClientThread::main_loop(int socket_fd)
555 this->socket_fd = socket_fd;
560 void RenderFarmClientThread::run()
562 // Create new memory space
567 waitpid(pid, &return_value, 0);
571 // Get the pid of the fork if inside the fork
576 int socket_fd = this->socket_fd;
578 init_client_keepalive();
580 // Get command to run
582 lock("RenderFarmClientThread::run");
583 get_command(socket_fd, &command);
586 //printf("RenderFarmClientThread::run command=%d\n", command);
590 case RENDERFARM_TUNER:
593 case RENDERFARM_PACKAGES:
594 do_packages(socket_fd);
602 void RenderFarmClientThread::init_client_keepalive()
604 keep_alive = new RenderFarmKeepalive(this);
606 watchdog = new RenderFarmWatchdog(0, this);
612 void RenderFarmClientThread::do_tuner(int socket_fd)
614 // Currently only 1 tuner driver. Maybe more someday.
615 DVBTune server(this);
621 void RenderFarmClientThread::do_packages(int socket_fd)
625 RenderPackage *package;
626 Asset *default_asset;
627 Preferences *preferences;
631 FarmPackageRenderer package_renderer(this, socket_fd);
636 //printf("RenderFarmClientThread::run 2\n");
638 preferences = new Preferences;
639 default_asset = new Asset;
640 package = new RenderPackage;
642 edl->create_objects();
649 //printf("RenderFarmClientThread::run 3\n");
650 read_preferences(socket_fd, preferences);
651 //printf("RenderFarmClientThread::run 4\n");
652 read_asset(socket_fd, default_asset);
653 //printf("RenderFarmClientThread::run 5\n");
654 read_edl(socket_fd, edl, preferences);
656 //printf("RenderFarmClientThread::run 6\n");
665 package_renderer.initialize(0,
673 //printf("RenderFarmClientThread::run 5\n");
674 result = read_package(socket_fd, package);
675 //printf("RenderFarmClientThread::run 6 %d\n", result);
681 //printf("RenderFarmClientThread::run 7\n");
683 result = send_completion(socket_fd);
691 if(package_renderer.render_package(package))
693 //printf("RenderFarmClientThread::run 8\n");
694 result = send_completion(socket_fd);
699 frames_per_second = package_renderer.frames_per_second;
700 // frames_per_second = (double)(package->video_end - package->video_start) /
701 // ((double)timer.get_difference() / 1000);
703 //printf("RenderFarmClientThread::run 9\n");
710 //printf("RenderFarmClientThread::run 9\n");
711 default_asset->Garbage::remove_user();
712 //printf("RenderFarmClientThread::run 10\n");
713 edl->Garbage::remove_user();
714 //printf("RenderFarmClientThread::run 11\n");
716 printf(_("RenderFarmClientThread::run: Session finished.\n"));
727 RenderFarmKeepalive::RenderFarmKeepalive(
728 RenderFarmClientThread *client_thread)
731 this->client_thread = client_thread;
735 RenderFarmKeepalive::~RenderFarmKeepalive()
742 void RenderFarmKeepalive::run()
751 //printf("RenderFarmKeepalive::run 1\n");
752 // watchdog thread kills this if it gets stuck
753 client_thread->ping_server();
754 //printf("RenderFarmKeepalive::run 10\n");
773 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
777 this->thread = thread;
778 this->socket_fd = socket_fd;
783 FarmPackageRenderer::~FarmPackageRenderer()
788 int FarmPackageRenderer::get_result()
790 thread->lock("FarmPackageRenderer::get_result");
791 thread->send_request_header(RENDERFARM_GET_RESULT,
793 unsigned char data[1];
795 if(thread->read_socket((char*)data, 1) != 1)
804 void FarmPackageRenderer::set_result(int value)
806 thread->lock("FarmPackageRenderer::set_result");
807 thread->send_request_header(RENDERFARM_SET_RESULT,
809 unsigned char data[1];
811 thread->write_socket((char*)data, 1);
815 void FarmPackageRenderer::set_progress(int64_t total_samples)
817 thread->lock("FarmPackageRenderer::set_progress");
818 thread->send_request_header(RENDERFARM_PROGRESS,
820 unsigned char datagram[8];
822 STORE_INT32(total_samples);
825 int64_t fixed = (!EQUIV(frames_per_second, 0.0)) ?
826 (int64_t)(frames_per_second * 65536.0) : 0;
830 thread->write_socket((char*)datagram, 8);
834 int FarmPackageRenderer::set_video_map(int64_t position, int value)
837 unsigned char datagram[8];
838 char return_value[1];
841 thread->lock("FarmPackageRenderer::set_video_map");
842 thread->send_request_header(RENDERFARM_SET_VMAP,
844 STORE_INT32(position);
846 thread->write_socket((char*)datagram, 8);
848 // Get completion since the GUI may be locked for a long time.
849 if(!thread->read_socket(return_value, 1))