r870: Merge 2.1:
[cinelerra_cv.git] / cinelerra / renderfarm.h
blob405283bbd0146bac76a0865dab1483df22ae8ec1
1 #ifndef RENDERFARM_H
2 #define RENDERFARM_H
5 #include "arraylist.h"
6 #include "asset.inc"
7 #include "brender.inc"
8 #include "bchash.inc"
9 #include "condition.inc"
10 #include "edl.inc"
11 #include "mutex.inc"
12 #include "mwindow.inc"
13 #include "packagedispatcher.inc"
14 #include "pluginserver.inc"
15 #include "preferences.inc"
16 #include "render.inc"
17 #include "renderfarm.inc"
18 #include "renderfarmclient.inc"
19 //#include "renderfarmfsserver.inc"
20 #include "thread.h"
22 #include <stdint.h>
25 // Renderfarm theory:
26 // The renderfarm starts a RenderFarmServerThread for each client
27 // listed in the preferences.
28 // The RenderFarmServerThread starts a RenderFarmWatchdog thread.
29 // write_socket and read_socket start the watchdog thread. If they don't
30 // return in a certain time, the watchdog thread assumes the client has crashed
31 // and kills RenderFarmServerThread.
32 // RenderFarmServerThread handles requests from the client once the
33 // connection is open. All the RenderFarmServerThread's are joined by the
34 // RenderFarmServer when the jobs are finished.
36 // On the client side, the process started by the user is a RenderFarmClient.
37 // It waits for connections from the server and starts a RenderFarmClientThread
38 // for each connection. RenderFarmClientThread is a thread but it in turn
39 // starts a fork for the actual rendering. A fork instead of a thread is
40 // used to avoid reentrancy problems with the
41 // codecs, but we still need a thread to join the process.
42 //
43 // The fork requests jobs from the server until the job table is empty
44 // or the server reports an error. This fork must poll the server
45 // after every frame for the error status. Also the fork creates a
46 // RenderFarmWatchdog thread to kill itself if a write_socket or read_socket
47 // doesn't return.
48 //
49 // RenderFarmClientThread detaches when finished.
50 // It doesn't account for the server command loop, which waits for read_socket
51 // indefinitely. This needs to be pinged periodically to keep the read_socket
52 // alive.
54 // Once, it tried to use a virtual file system to allow rendering clients without
55 // mounting the filesystem of the server. This proved impractical because of
56 // the many odd schemes used by file libraries. Abstracting "open" didn't
57 // work. Read ahead and caching were required to get decent performance.
59 // Whether it cleans up when timed out is unknown.
61 // Request format
62 // 1 byte -> request code
63 // 4 bytes -> size of packet exclusive
64 // size of packet -> data
68 // General reply format
69 // 4 bytes -> size of packet exclusive
70 // size of packet -> data
72 #define STORE_INT32(value) \
73 datagram[i++] = (((uint32_t)(value)) >> 24) & 0xff; \
74 datagram[i++] = (((uint32_t)(value)) >> 16) & 0xff; \
75 datagram[i++] = (((uint32_t)(value)) >> 8) & 0xff; \
76 datagram[i++] = ((uint32_t)(value)) & 0xff;
78 #define STORE_INT64(value) \
79 datagram[i++] = (((uint64_t)(value)) >> 56) & 0xff; \
80 datagram[i++] = (((uint64_t)(value)) >> 48) & 0xff; \
81 datagram[i++] = (((uint64_t)(value)) >> 40) & 0xff; \
82 datagram[i++] = (((uint64_t)(value)) >> 32) & 0xff; \
83 datagram[i++] = (((uint64_t)(value)) >> 24) & 0xff; \
84 datagram[i++] = (((uint64_t)(value)) >> 16) & 0xff; \
85 datagram[i++] = (((uint64_t)(value)) >> 8) & 0xff; \
86 datagram[i++] = ((uint64_t)(value)) & 0xff;
88 #define READ_INT32(data) \
89 ((((uint32_t)(data)[0]) << 24) | \
90 (((uint32_t)(data)[1]) << 16) | \
91 (((uint32_t)(data)[2]) << 8) | \
92 ((uint32_t)(data)[3]))
94 #define READ_INT64(data) \
95 ((((uint64_t)(data)[0]) << 56) | \
96 (((uint64_t)(data)[1]) << 48) | \
97 (((uint64_t)(data)[2]) << 40) | \
98 (((uint64_t)(data)[3]) << 32) | \
99 (((uint64_t)(data)[4]) << 24) | \
100 (((uint64_t)(data)[5]) << 16) | \
101 (((uint64_t)(data)[6]) << 8) | \
102 ((uint64_t)(data)[7]))
105 // Request codes to be used in both client and server.
106 enum
108 RENDERFARM_NONE,
109 RENDERFARM_PREFERENCES, // 0 Get preferences on startup
110 RENDERFARM_ASSET, // Get output format on startup
111 RENDERFARM_EDL, // Get EDL on startup
112 RENDERFARM_PACKAGE, // Get one package after another to render
113 RENDERFARM_PROGRESS, // Update completion total
114 RENDERFARM_SET_RESULT, // Update error status
115 RENDERFARM_GET_RESULT, // Retrieve error status
116 RENDERFARM_DONE, // Quit
117 RENDERFARM_SET_VMAP, // 8 Update video map in background rendering
118 RENDERFARM_COMMAND, // Get the client to run
119 RENDERFARM_TUNER, // Run a tuner server
120 RENDERFARM_PACKAGES, // Run packages
121 RENDERFARM_KEEPALIVE, // Keep alive
123 // VFS commands
124 RENDERFARM_FOPEN,
125 RENDERFARM_FCLOSE,
126 RENDERFARM_REMOVE,
127 RENDERFARM_RENAME,
128 RENDERFARM_FGETC,
129 RENDERFARM_FPUTC,
130 RENDERFARM_FREAD,
131 RENDERFARM_FWRITE,
132 RENDERFARM_FSEEK,
133 RENDERFARM_FTELL,
134 RENDERFARM_STAT,
135 RENDERFARM_STAT64,
136 RENDERFARM_FGETS,
137 RENDERFARM_FILENO
141 class RenderFarmServer
143 public:
144 // MWindow is required to get the plugindb to save the EDL.
145 RenderFarmServer(ArrayList<PluginServer*> *plugindb,
146 PackageDispatcher *packages,
147 Preferences *preferences,
148 int use_local_rate,
149 int *result_return,
150 int64_t *total_return,
151 Mutex *total_return_lock,
152 Asset *default_asset,
153 EDL *edl,
154 BRender *brender);
155 virtual ~RenderFarmServer();
158 // Open connections to clients.
159 int start_clients();
160 // The render farm must wait for all the clients to finish.
161 int wait_clients();
163 // Likewise the render farm must check the internal render loop before
164 // dispatching the next job and whenever a client queries for errors.
167 ArrayList<RenderFarmServerThread*> clients;
168 ArrayList<PluginServer*> *plugindb;
169 // MWindow *mwindow;
170 PackageDispatcher *packages;
171 Preferences *preferences;
172 // Use master node's framerate
173 int use_local_rate;
174 // These values are shared between the local renderer and the
175 // renderfarm server threads.
176 // The error code.
177 // Any nonzero value is an error and stops rendering.
178 int *result_return;
179 // The total number of frames completed
180 int64_t *total_return;
181 Mutex *total_return_lock;
182 Asset *default_asset;
183 EDL *edl;
184 Mutex *client_lock;
185 BRender *brender;
189 class RenderFarmServerThread : public Thread
191 public:
192 RenderFarmServerThread(ArrayList<PluginServer*> *plugindb,
193 RenderFarmServer *server,
194 int number);
195 ~RenderFarmServerThread();
198 // Used by both client and server
199 int write_int64(int64_t value);
200 int64_t read_int64(int *error);
201 // Inserts header and writes string to socket
202 int write_string(char *string);
203 static int open_client(char *hostname, int port);
207 // Used by server only
208 int read_socket(char *data, int len);
209 int write_socket(char *data, int len);
210 int start_loop();
211 void send_preferences();
212 void send_asset();
213 void send_edl();
214 void send_package(unsigned char *buffer);
215 void set_progress(unsigned char *buffer);
216 int set_video_map(unsigned char *buffer);
217 void set_result(unsigned char *buffer);
218 void get_result();
219 void reallocate_buffer(int size);
222 void run();
224 // MWindow *mwindow;
225 ArrayList<PluginServer*> *plugindb;
226 RenderFarmServer *server;
227 RenderFarmWatchdog *watchdog;
228 int socket_fd;
229 int number;
230 // Rate of last job or 0
231 double frames_per_second;
232 // Pointer to default asset
233 Asset *default_asset;
234 // These objects can be left dangling of the watchdog kills the thread.
235 // They are deleted in the destructor.
236 unsigned char *buffer;
237 int64_t buffer_allocated;
238 char *datagram;
241 class RenderFarmWatchdog : public Thread
243 public:
244 // use_pid - causes it to kill the pid instead of cancel the thread
245 // Used for client.
246 RenderFarmWatchdog(RenderFarmServerThread *server,
247 RenderFarmClientThread *client);
248 ~RenderFarmWatchdog();
250 // Called at the beginning of a socket read
251 void begin_request();
252 // Called when a socket read succeeds
253 void end_request();
254 void run();
256 RenderFarmServerThread *server;
257 RenderFarmClientThread *client;
258 Condition *next_request;
259 Condition *request_complete;
260 int done;
261 int pid;
268 #endif