Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

renderfarmclient.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "assets.h"
00003 #include "clip.h"
00004 #include "defaults.h"
00005 #include "edl.h"
00006 #include "filesystem.h"
00007 #include "filexml.h"
00008 #include "language.h"
00009 #include "mwindow.h"
00010 #include "pluginserver.h"
00011 #include "preferences.h"
00012 #include "renderfarm.h"
00013 #include "renderfarmclient.h"
00014 //#include "renderfarmfsclient.h"
00015 #include "sighandler.h"
00016 
00017 #include <arpa/inet.h>
00018 #include <errno.h>
00019 #include <fcntl.h>
00020 #include <netdb.h>
00021 #include <netinet/in.h>
00022 #include <stdio.h>
00023 #include <string.h>
00024 #include <sys/socket.h>
00025 #include <sys/types.h>
00026 #include <sys/un.h>
00027 #include <sys/wait.h>
00028 #include <unistd.h>
00029 
00030 
00031 
00032 
00033 // The render client waits for connections from the server.
00034 // Then it starts a thread for each connection.
00035 RenderFarmClient::RenderFarmClient(int port, 
00036         char *deamon_path, 
00037         int nice_value,
00038         char *config_path)
00039 {
00040         this->port = port;
00041         this->deamon_path = deamon_path;
00042         SigHandler *signals = new SigHandler;
00043         signals->initialize();
00044 
00045         this_pid = getpid();
00046         nice(nice_value);
00047 
00048         thread = new RenderFarmClientThread(this);
00049 
00050         MWindow::init_defaults(boot_defaults, config_path);
00051         boot_preferences = new Preferences;
00052         boot_preferences->load_defaults(boot_defaults);
00053         MWindow::init_plugins(boot_preferences, plugindb, 0);
00054 }
00055 
00056 
00057 
00058 
00059 RenderFarmClient::~RenderFarmClient()
00060 {
00061         delete thread;
00062         delete boot_defaults;
00063         delete boot_preferences;
00064         plugindb->remove_all_objects();
00065         delete plugindb;
00066 }
00067 
00068 
00069 void RenderFarmClient::main_loop()
00070 {
00071         int socket_fd;
00072 
00073 
00074 
00075 // Open listening port
00076 
00077         if(!deamon_path)
00078         {
00079                 struct sockaddr_in addr;
00080 
00081                 addr.sin_family = AF_INET;
00082                 addr.sin_port = htons((unsigned short)port);
00083                 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00084 
00085                 if((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
00086                 {
00087                         perror(_("RenderFarmClient::main_loop: socket"));
00088                         return;
00089                 }
00090 
00091                 if(bind(socket_fd, 
00092                         (struct sockaddr*)&addr, 
00093                         sizeof(addr)) < 0)
00094                 {
00095                         fprintf(stderr, 
00096                                 _("RenderFarmClient::main_loop: bind port %d: %s"),
00097                                 port,
00098                                 strerror(errno));
00099                         return;
00100                 }
00101         }
00102         else
00103         {
00104                 struct sockaddr_un addr;
00105                 addr.sun_family = AF_FILE;
00106                 strcpy(addr.sun_path, deamon_path);
00107                 int size = (offsetof(struct sockaddr_un, sun_path) + 
00108                         strlen(deamon_path) + 1);
00109 
00110                 if((socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
00111                 {
00112                         perror(_("RenderFarmClient::main_loop: socket"));
00113                         return;
00114                 }
00115 
00116                 if(bind(socket_fd, 
00117                         (struct sockaddr*)&addr, 
00118                         size) < 0)
00119                 {
00120                         fprintf(stderr, 
00121                                 _("RenderFarmClient::main_loop: bind path %s: %s\n"),
00122                                 deamon_path,
00123                                 strerror(errno));
00124                         return;
00125                 }
00126         }
00127 
00128 // Wait for connections
00129         printf("RenderFarmClient::main_loop: client started\n");
00130         while(1)
00131         {
00132                 if(listen(socket_fd, 256) < 0)
00133         {
00134                 perror(_("RenderFarmClient::main_loop: listen"));
00135                 return;
00136         }
00137 
00138                 int new_socket_fd;
00139 
00140 
00141 
00142                 if(!deamon_path)
00143                 {
00144                         struct sockaddr_in clientname;
00145                         socklen_t size = sizeof(clientname);
00146                 if((new_socket_fd = accept(socket_fd,
00147                                 (struct sockaddr*)&clientname, 
00148                                                 &size)) < 0)
00149                 {
00150                         perror(_("RenderFarmClient::main_loop: accept"));
00151                         return;
00152                 }
00153                         else
00154                         {
00155 //printf("RenderFarmClient::main_loop: Session started from %s\n", inet_ntoa(clientname.sin_addr));
00156                                 thread->main_loop(new_socket_fd);
00157                         }
00158                 }
00159                 else
00160                 {
00161                         struct sockaddr_un clientname;
00162                         socklen_t size = sizeof(clientname);
00163                 if((new_socket_fd = accept(socket_fd,
00164                                 (struct sockaddr*)&clientname, 
00165                                                 &size)) < 0)
00166                 {
00167                         perror(_("RenderFarmClient::main_loop: accept"));
00168                         return;
00169                 }
00170                         else
00171                         {
00172 //printf("RenderFarmClient::main_loop: Session started from %s\n", clientname.sun_path);
00173                                 thread->main_loop(new_socket_fd);
00174                         }
00175                 }
00176         }
00177 }
00178 
00179 void RenderFarmClient::kill_client()
00180 {
00181 printf("RenderFarmClient::kill_client 1\n");
00182         if(deamon_path)
00183         {
00184 printf("RenderFarmClient::kill_client 2\n");
00185                 remove(deamon_path);
00186                 kill(this_pid, SIGKILL);
00187         }
00188 }
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 // The thread requests jobs from the server until the job table is empty
00201 // or the server reports an error.  This thread must poll the server
00202 // after every frame for the error status.
00203 // Detaches when finished.
00204 RenderFarmClientThread::RenderFarmClientThread(RenderFarmClient *client)
00205  : Thread()
00206 {
00207         this->client = client;
00208         frames_per_second = 0;
00209         Thread::set_synchronous(0);
00210 //      fs_client = 0;
00211         mutex_lock = new Mutex("RenderFarmClientThread::mutex_lock");
00212 }
00213 
00214 RenderFarmClientThread::~RenderFarmClientThread()
00215 {
00216 //      if(fs_client) delete fs_client;
00217         delete mutex_lock;
00218 }
00219 
00220 
00221 int RenderFarmClientThread::send_request_header(int request, 
00222         int len)
00223 {
00224         unsigned char datagram[5];
00225         datagram[0] = request;
00226 
00227         int i = 1;
00228         STORE_INT32(len);
00229 // printf("RenderFarmClientThread::send_request_header %d %02x%02x%02x%02x%02x\n",
00230 // request, datagram[0], datagram[1], datagram[2], datagram[3], datagram[4]);
00231 
00232         return (write_socket((char*)datagram, 
00233                 5, 
00234                 RENDERFARM_TIMEOUT) != 5);
00235 }
00236 
00237 int RenderFarmClientThread::write_socket(char *data, int len, int timeout)
00238 {
00239         int result = RenderFarmServerThread::write_socket(socket_fd, 
00240                 data, 
00241                 len, 
00242                 timeout);
00243 // Assume the stream is offset and give up future accesses.
00244         if(result <= 0) abort();
00245 }
00246 
00247 int RenderFarmClientThread::read_socket(char *data, int len, int timeout)
00248 {
00249         int result = RenderFarmServerThread::read_socket(socket_fd, 
00250                 data, 
00251                 len, 
00252                 timeout);
00253 // Assume the stream is offset and give up future accesses.
00254         if(result <= 0) abort();
00255 }
00256 
00257 void RenderFarmClientThread::abort()
00258 {
00259         send_completion(socket_fd);
00260         close(socket_fd);
00261         exit(1);
00262 }
00263 
00264 void RenderFarmClientThread::lock(char *location)
00265 {
00266         mutex_lock->lock(location);
00267 }
00268 
00269 void RenderFarmClientThread::unlock()
00270 {
00271         mutex_lock->unlock();
00272 }
00273 
00274 void RenderFarmClientThread::read_string(int socket_fd, char* &string)
00275 {
00276         unsigned char header[4];
00277         if(read_socket((char*)header, 4, RENDERFARM_TIMEOUT) != 4)
00278         {
00279                 string = 0;
00280                 return;
00281         }
00282 
00283         int64_t len = (((u_int32_t)header[0]) << 24) | 
00284                                 (((u_int32_t)header[1]) << 16) | 
00285                                 (((u_int32_t)header[2]) << 8) | 
00286                                 ((u_int32_t)header[3]);
00287 
00288         if(len)
00289         {
00290                 string = new char[len];
00291                 if(read_socket(string, len, RENDERFARM_TIMEOUT) != len)
00292                 {
00293                         delete [] string;
00294                         string = 0;
00295                 }
00296         }
00297         else
00298                 string = 0;
00299 
00300 }
00301 
00302 
00303 void RenderFarmClientThread::read_preferences(int socket_fd, 
00304         Preferences *preferences)
00305 {
00306         send_request_header(RENDERFARM_PREFERENCES, 
00307                 0);
00308 
00309         char *string;
00310         read_string(socket_fd, string);
00311 
00312         Defaults defaults;
00313         defaults.load_string((char*)string);
00314         preferences->load_defaults(&defaults);
00315 
00316         delete [] string;
00317 }
00318 
00319 
00320 
00321 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
00322 {
00323         send_request_header(RENDERFARM_ASSET, 
00324                 0);
00325 
00326         char *string1;
00327         char *string2;
00328         read_string(socket_fd, string1);
00329         read_string(socket_fd, string2);
00330 
00331 
00332 
00333         FileXML file;
00334         file.read_from_string((char*)string2);
00335         asset->read(&file);
00336         
00337 
00338 
00339         Defaults defaults;
00340         defaults.load_string((char*)string1);
00341         asset->load_defaults(&defaults,
00342                 0,
00343                 1,
00344                 1,
00345                 1,
00346                 1,
00347                 1);
00348 
00349         delete [] string1;
00350         delete [] string2;
00351 }
00352 
00353 void RenderFarmClientThread::read_edl(int socket_fd, 
00354         EDL *edl, 
00355         Preferences *preferences)
00356 {
00357         send_request_header(RENDERFARM_EDL, 
00358                 0);
00359 
00360         char *string;
00361         read_string(socket_fd, string);
00362 
00363 //printf("RenderFarmClientThread::read_edl 1\n");
00364 
00365         FileXML file;
00366         file.read_from_string((char*)string);
00367         delete [] string;
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376         edl->load_xml(client->plugindb,
00377                 &file, 
00378                 LOAD_ALL);
00379 
00380 
00381 
00382 // Tag input paths for VFS here.
00383 // Create VFS object.
00384         FileSystem fs;
00385 //      if(preferences->renderfarm_vfs)
00386 //      {
00387 //              fs_client = new RenderFarmFSClient(this);
00388 //              fs_client->initialize();
00389 // 
00390 //              for(Asset *asset = edl->assets->first;
00391 //                      asset;
00392 //                      asset = asset->next)
00393 //              {
00394 //                      char string2[BCTEXTLEN];
00395 //                      strcpy(string2, asset->path);
00396 //                      sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", string2);
00397 //              }
00398 //      }
00399 
00400 //      for(Asset *asset = edl->assets->first;
00401 //              asset;
00402 //              asset = asset->next)
00403 //      {
00404 //              char string2[BCTEXTLEN];
00405 //              strcpy(string2, asset->path);
00406 //              fs.join_names(asset->path, preferences->renderfarm_mountpoint, string2);
00407 //      }
00408 
00409 
00410 //edl->dump();
00411 }
00412 
00413 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
00414 {
00415         send_request_header(RENDERFARM_PACKAGE, 
00416                 4);
00417 
00418         unsigned char datagram[5];
00419         int i = 0;
00420 
00421 
00422 // Fails if -ieee isn't set.
00423         int64_t fixed = !EQUIV(frames_per_second, 0.0) ? 
00424                 (int64_t)(frames_per_second * 65536.0) : 0;
00425         STORE_INT32(fixed);
00426         write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
00427 
00428 
00429 //printf("RenderFarmClientThread::read_package 1 %f %ld\n", frames_per_second, fixed);
00430         char *data;
00431         unsigned char *data_ptr;
00432         read_string(socket_fd, data);
00433 //printf("RenderFarmClientThread::read_package 2 %p\n", data);
00434 // Signifies end of session.
00435         if(!data) 
00436         {
00437 //              printf(_("RenderFarmClientThread::read_package no output path recieved.\n"));
00438                 return 1;
00439         }
00440 
00441 //printf("RenderFarmClientThread::read_package 2\n");
00442 
00443 
00444         data_ptr = (unsigned char*)data;
00445         strcpy(package->path, data);
00446         data_ptr += strlen(package->path);
00447         data_ptr++;
00448         package->audio_start = READ_INT32(data_ptr);
00449         data_ptr += 4;
00450         package->audio_end = READ_INT32(data_ptr);
00451         data_ptr += 4;
00452         package->video_start = READ_INT32(data_ptr);
00453         data_ptr += 4;
00454         package->video_end = READ_INT32(data_ptr);
00455         data_ptr += 4;
00456         package->use_brender = READ_INT32(data_ptr);
00457 
00458         delete [] data;
00459 
00460         return 0;
00461 }
00462 
00463 int RenderFarmClientThread::send_completion(int socket_fd)
00464 {
00465         return send_request_header(RENDERFARM_DONE, 
00466                 0);
00467 }
00468 
00469 
00470 
00471 
00472 void RenderFarmClientThread::main_loop(int socket_fd)
00473 {
00474          this->socket_fd = socket_fd;
00475          Thread::start();
00476 }
00477 
00478 void RenderFarmClientThread::run()
00479 {
00480 // Create new memory space
00481         int pid = fork();
00482         if(pid != 0)
00483         {
00484                 int return_value;
00485                 waitpid(pid, &return_value, 0);
00486                 return;
00487         }
00488 
00489 
00490 
00491 
00492 
00493 
00494         int socket_fd = this->socket_fd;
00495 //printf("RenderFarmClientThread::run 1\n");
00496         EDL *edl;
00497         RenderPackage *package;
00498         Asset *default_asset;
00499         Preferences *preferences;
00500         FarmPackageRenderer package_renderer(this, socket_fd);
00501         int result = 0;
00502 
00503 //printf("RenderFarmClientThread::run 2\n");
00504 // Read settings
00505         preferences = new Preferences;
00506         default_asset = new Asset;
00507         package = new RenderPackage;
00508         edl = new EDL;
00509         edl->create_objects();
00510 
00511 //printf("RenderFarmClientThread::run 3\n");
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519         read_preferences(socket_fd, preferences);
00520 //printf("RenderFarmClientThread::run 3\n");
00521         read_asset(socket_fd, default_asset);
00522 //printf("RenderFarmClientThread::run 3\n");
00523         read_edl(socket_fd, edl, preferences);
00524 //edl->dump();
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 //printf("RenderFarmClientThread::run 4\n");
00533 
00534         package_renderer.initialize(0,
00535                         edl, 
00536                         preferences, 
00537                         default_asset,
00538                         client->plugindb);
00539 //printf("RenderFarmClientThread::run 5\n");
00540 
00541 // Read packages
00542         while(1)
00543         {
00544                 result = read_package(socket_fd, package);
00545 //printf("RenderFarmClientThread::run 6 %d\n", result);
00546 
00547 
00548 // Finished list
00549                 if(result)
00550                 {
00551 //printf("RenderFarmClientThread::run 7 %d\n", result);
00552 
00553                         result = send_completion(socket_fd);
00554                         break;
00555                 }
00556 
00557                 Timer timer;
00558                 timer.update();
00559 
00560 // Error
00561                 if(package_renderer.render_package(package))
00562                 {
00563 //printf("RenderFarmClientThread::run 8\n");
00564                         result = send_completion(socket_fd);
00565                         break;
00566                 }
00567 
00568                 frames_per_second = (double)(package->video_end - package->video_start) / 
00569                         ((double)timer.get_difference() / 1000);
00570 
00571 //printf("RenderFarmClientThread::run 9\n");
00572 
00573 
00574 
00575         }
00576 
00577 
00578 //printf("RenderFarmClientThread::run 9\n");
00579         delete default_asset;
00580 //printf("RenderFarmClientThread::run 10\n");
00581         delete edl;
00582 //printf("RenderFarmClientThread::run 11\n");
00583         delete preferences;
00584 //printf("RenderFarmClientThread::run 12\n");
00585 printf(_("RenderFarmClientThread::run: Session finished.\n"));
00586 
00587 // Socket error should be the only cause of this
00588         if(result)
00589         {
00590                 ;
00591         }
00592 
00593         _exit(0);
00594 }
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
00604                 int socket_fd)
00605  : PackageRenderer()
00606 {
00607         this->thread = thread;
00608         this->socket_fd = socket_fd;
00609 }
00610 
00611 
00612 
00613 FarmPackageRenderer::~FarmPackageRenderer()
00614 {
00615 }
00616 
00617 
00618 int FarmPackageRenderer::get_result()
00619 {
00620         thread->lock("FarmPackageRenderer::get_result");
00621         thread->send_request_header(RENDERFARM_GET_RESULT, 
00622                 0);
00623         unsigned char data[1];
00624         data[0] = 1;
00625         if(thread->read_socket((char*)data, 1, RENDERFARM_TIMEOUT) != 1)
00626         {
00627                 thread->unlock();
00628                 return 1;
00629         }
00630         thread->unlock();
00631         return data[0];
00632 }
00633 
00634 void FarmPackageRenderer::set_result(int value)
00635 {
00636         thread->lock("FarmPackageRenderer::set_result");
00637         thread->send_request_header(RENDERFARM_SET_RESULT, 
00638                 1);
00639         unsigned char data[1];
00640         data[0] = value;
00641         thread->write_socket((char*)data, 1, RENDERFARM_TIMEOUT);
00642         thread->unlock();
00643 }
00644 
00645 void FarmPackageRenderer::set_progress(int64_t total_samples)
00646 {
00647         thread->lock("FarmPackageRenderer::set_progress");
00648         thread->send_request_header(RENDERFARM_PROGRESS, 
00649                 4);
00650         unsigned char datagram[4];
00651         int i = 0;
00652         STORE_INT32(total_samples);
00653         thread->write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
00654         thread->unlock();
00655 }
00656 
00657 int FarmPackageRenderer::set_video_map(int64_t position, int value)
00658 {
00659         int result = 0;
00660         unsigned char datagram[8];
00661         char return_value[1];
00662         int i = 0;
00663 
00664         thread->lock("FarmPackageRenderer::set_video_map");
00665         thread->send_request_header(RENDERFARM_SET_VMAP, 
00666                 8);
00667         STORE_INT32(position);
00668         STORE_INT32(value);
00669         thread->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT);
00670 
00671 // Get completion since the GUI may be locked for a long time.
00672         if(!thread->read_socket(return_value, 1, RENDERFARM_TIMEOUT))
00673         {
00674                 result = 1;
00675         }
00676 
00677         thread->unlock();
00678         return result;
00679 }
00680 

Generated on Sun Jan 8 13:39:00 2006 for Cinelerra-svn by  doxygen 1.4.4