From 2af4e5e3900fae162d87ec26cccc051aeb131a56 Mon Sep 17 00:00:00 2001 From: Bruce Allen Date: Fri, 10 Dec 2004 23:33:41 +0000 Subject: [PATCH] David, here's a rough pass, I haven't even tried to compile it. Please read comments in-line. I think the major shortcoming is that most (all?) apps will want to use 'handle' to resolve their own functions to communicate data from worker to app graphics. Perhaps we should provide an additional argument to boinc_init_graphics_lib() for that purpose? At the right point, after sucessful dlopen(), boinc_init_graphics_lib() will call that user-supplied function (if not NULL) passing it handle. On return boinc_init_graphics_lib() will then carry on and start graphics. It's fun working on a file that's not in Makefile. No guilt! svn path=/trunk/boinc/; revision=4816 --- api/graphics_lib.C | 108 +++++++++++++++++++++++++++++++++++++++++++-- checkin_notes | 18 ++++++++ 2 files changed, 122 insertions(+), 4 deletions(-) diff --git a/api/graphics_lib.C b/api/graphics_lib.C index 2315ae0784..47f4c0d9a7 100644 --- a/api/graphics_lib.C +++ b/api/graphics_lib.C @@ -23,10 +23,110 @@ // the host has X11 and OpenGL libraries. #include - #include "graphics_lib.h" -int boinc_init_graphics_lib(void (*worker)(), char* libname) { - dlopen(libname, RTLD_GLOBAL); - // look up boinc_init_graphics_impl; call it +// for prototype of boinc_init_options_general(), boinc_init, boinc_finish +#include "boinc_api.h" + +#define BOINC_STRLEN 512 + +// Many applications will NOT want to call this routine. Instead +// they'll want to cut and paste this code into their own application. +// This is because they will want to use 'handle' below to resolve +// functions that are included in the apps shared library, which +// communicate information about the work in progress to the +// app_graphics_render() routine, and other graphics routines. + + +// This routine never returns. If a problem arises, it calls +// boinc_finish(nonzero). +// +// First argument: worker function +// +// Second argument: argv[0] from command line arguments. This is the +// executable name, and is used to derive the shared object library +// name: executable_name.so + +int boinc_init_graphics_lib(void (*worker)(), char* argv0) { + + // name of shared object library: same as executable_name.so + char graphics_lib[BOINC_STRLEN]; + // boinc-resolved version of the same + char resolved_name[BOINC_STRLEN]; + char *ptr; + void *handle; + int retval; + char *errormsg; + + // DAVID -- WARNING -- TO BE USABLE IN C YOU NEED TO GIVE + // boinc_init_options_general() A PURE C PROTOTYPE NOT C++! THIS + // CURRENTLY WON'T WORK FOR E@h. + int (*boinc_init_graphics_impl_hook)(void (*worker)(), int (*init_options)(BOINC_OPTIONS& opt)); + + /* figure out name of executable, and append .so */ + if ((ptr = strrchr(argv0, '/'))) + ptr++; + else + ptr = argv0; + strncat(graphics_lib, ".so", BOINC_STRLEN); + graphics_lib[BOINC_STRLEN-1]='\0'; + + /* boinc-resolve library name: it could be a XML symlink */ + if (boinc_resolve_filename(graphics_lib, resolved_name, BOINC_STRLEN)) { +#if 0 + // for debugging + fprintf(stderr, "Unable to boinc_resolve name of shared object file %s\n", graphics_lib); +#endif + goto no_graphics; + } + + // now get handle for shared library + if (!(handle = dlopen(resolved_name, RTLD_NOW))) { +#if 0 + // for debugging + errormsg=dlerror(); + fprintf (stderr, "dlopen() failed: %s\nNo graphics.\n", ?errormsg:errormsg:""); +#endif + goto no_graphics; + } + + if (!(boinc_init_graphics_impl_hook = dlsym(handle,"boinc_init_graphics_impl"))) { +#if 0 + // for debugging + errormsg=dlerror(); + fprintf(stderr, "dlsym() couldn't find boinc_init_graphics_impl in %s\n", resolved_name); +#endif + goto no_graphics; + } + +#if 0 + // Applications that wish to make use of functions in the shared + // library, to communicate data from the worker function to the + // graphics rendinging functions should paste them in there: + myfunction1_hook=dlsym("myfunction1"); + myfunction2_hook=dlsym("myfunction2"); + myfunction3_hook=dlsym("myfunction3"); +#endif + + // this should never return + retval = boinc_init_graphics_impl_hook(worker, boinc_init_options_general); + + if (retval) { +#if 0 + fprintf(stderr,"boinc_init_graphics_impl() returned %d: unable to create worker thread\n", retval); +#endif + } + + boinc_finish(1+retval); + + no_graphics: + // unable to resolve the shared object file, or unable to resolve + // dependencies on machine, or unable to find needed symbol in + // library + boinc_init(); + worker(); + + // worker() should call boinc_finish so we should NEVER get here! + boinc_finish(1); } + diff --git a/checkin_notes b/checkin_notes index 329b7df3d4..5b6ea46963 100755 --- a/checkin_notes +++ b/checkin_notes @@ -21089,3 +21089,21 @@ David 10 Dec 2004 sched/ transitioner.C + +Bruce 10 Dec 2004 + + David, here's a rough pass, I haven't even tried to compile + it. Please read comments in-line. I think the major + shortcoming is + that most (all?) apps will want to use 'handle' to resolve their + own functions to communicate data from worker to app graphics. + Perhaps we should provide an additional argument to + boinc_init_graphics_lib() for that purpose? At the right point, + after sucessful dlopen(), boinc_init_graphics_lib() will call + that user-supplied function (if not NULL) passing it handle. + On return boinc_init_graphics_lib() will then carry on and start + graphics. + It's fun working on a file that's not in Makefile. No guilt! + + api/ + graphics_lib.C