Implement base construct of new external renderer. CLI parameters still not implemented. Currently NULL is passed to init func. Forking implemented but not tested
This commit is contained in:
parent
f15e82b5dc
commit
f153485996
@ -30,8 +30,12 @@
|
|||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <gds-render/output-renderers/external-renderer.h>
|
#include <gds-render/output-renderers/external-renderer.h>
|
||||||
|
#include <gds-render/version.h>
|
||||||
|
|
||||||
|
#define FORCE_FORK 0U /**< @brief if != 0, then forking is forced regardless of the shared object's settings */
|
||||||
|
|
||||||
struct _ExternalRenderer {
|
struct _ExternalRenderer {
|
||||||
GdsOutputRenderer parent;
|
GdsOutputRenderer parent;
|
||||||
@ -58,9 +62,13 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
|
|||||||
const char *output_file, double scale, const char *so_path)
|
const char *output_file, double scale, const char *so_path)
|
||||||
{
|
{
|
||||||
int (*so_render_func)(struct gds_cell *, GList *, const char *, double) = NULL;
|
int (*so_render_func)(struct gds_cell *, GList *, const char *, double) = NULL;
|
||||||
|
int (*so_init_func)(const char *, const char *) = NULL;
|
||||||
void *so_handle = NULL;
|
void *so_handle = NULL;
|
||||||
char *error_msg;
|
char *error_msg;
|
||||||
|
int forking_req;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
pid_t fork_pid = 0;
|
||||||
|
int forked_status;
|
||||||
|
|
||||||
if (!so_path) {
|
if (!so_path) {
|
||||||
fprintf(stderr, "Path to shared object not set!\n");
|
fprintf(stderr, "Path to shared object not set!\n");
|
||||||
@ -78,7 +86,7 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
|
|||||||
return -2000;
|
return -2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load symbol from library */
|
/* Load rendering symbol from library */
|
||||||
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))
|
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))
|
||||||
dlsym(so_handle, xstr(EXTERNAL_LIBRARY_RENDER_FUNCTION));
|
dlsym(so_handle, xstr(EXTERNAL_LIBRARY_RENDER_FUNCTION));
|
||||||
error_msg = dlerror();
|
error_msg = dlerror();
|
||||||
@ -87,13 +95,47 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
|
|||||||
goto ret_close_so_handle;
|
goto ret_close_so_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute */
|
/* Load the init function */
|
||||||
if (so_render_func) {
|
so_init_func = (int (*)(const char *, const char *))dlsym(so_handle, xstr(EXTERNAL_LIBRARY_INIT_FUNCTION));
|
||||||
g_message("Calling external renderer.");
|
error_msg = dlerror();
|
||||||
ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale);
|
if (error_msg != NULL) {
|
||||||
g_message("External renderer finished.");
|
fprintf(stderr, "Rendering function not found in library:\n%s\n", error_msg);
|
||||||
|
goto ret_close_so_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if forking is requested */
|
||||||
|
if (dlsym(so_handle, xstr(EXTERNAL_LIBRARY_FORK_REQUEST)))
|
||||||
|
forking_req = 1;
|
||||||
|
else if (FORCE_FORK)
|
||||||
|
forking_req = 1;
|
||||||
|
else
|
||||||
|
forking_req = 0;
|
||||||
|
|
||||||
|
/* Execute */
|
||||||
|
|
||||||
|
g_message("Calling external renderer.");
|
||||||
|
|
||||||
|
if (forking_req)
|
||||||
|
fork_pid = fork();
|
||||||
|
if (fork_pid != 0)
|
||||||
|
goto end_forked;
|
||||||
|
|
||||||
|
// TODO: Get parameters form command line and pass here
|
||||||
|
ret = so_init_func(NULL, _app_version_string);
|
||||||
|
if (!ret)
|
||||||
|
ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale);
|
||||||
|
|
||||||
|
if (forking_req)
|
||||||
|
exit(ret);
|
||||||
|
|
||||||
|
end_forked:
|
||||||
|
if (forking_req) {
|
||||||
|
waitpid(fork_pid, &forked_status, 0);
|
||||||
|
ret = WEXITSTATUS(forked_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_message("External renderer finished.");
|
||||||
|
|
||||||
ret_close_so_handle:
|
ret_close_so_handle:
|
||||||
dlclose(so_handle);
|
dlclose(so_handle);
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user