Revision: 75499
http://sourceforge.net/p/brlcad/code/75499
Author: starseeker
Date: 2020-04-21 18:11:41 +0000 (Tue, 21 Apr 2020)
Log Message:
-----------
Experiment with using the bu_init.cpp approach to populate a list of available
libdm backends at library load time.
Modified Paths:
--------------
brlcad/branches/dm-fb-merge/src/libdm/CMakeLists.txt
brlcad/branches/dm-fb-merge/src/libdm/include/private.h
Added Paths:
-----------
brlcad/branches/dm-fb-merge/src/libdm/dm_init.cpp
brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.cpp
Removed Paths:
-------------
brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.c
Modified: brlcad/branches/dm-fb-merge/src/libdm/CMakeLists.txt
===================================================================
--- brlcad/branches/dm-fb-merge/src/libdm/CMakeLists.txt 2020-04-21
17:16:59 UTC (rev 75498)
+++ brlcad/branches/dm-fb-merge/src/libdm/CMakeLists.txt 2020-04-21
18:11:41 UTC (rev 75499)
@@ -138,8 +138,9 @@
axes.c
clip.c
dm-generic.c
+ dm_init.cpp
dm_obj.c
- dm_plugins.c
+ dm_plugins.cpp
dm_util.c
fb_generic.c
fb_log.c
@@ -162,7 +163,8 @@
vers.c
)
set_property(SOURCE dm_obj.c APPEND PROPERTY COMPILE_DEFINITIONS
FB_USE_INTERNAL_API)
-set_property(SOURCE dm_plugins.c APPEND PROPERTY COMPILE_DEFINITIONS
"DM_PLUGIN_SUFFIX=\"${CMAKE_SHARED_LIBRARY_SUFFIX}\"")
+set_property(SOURCE dm_plugins.cpp APPEND PROPERTY COMPILE_DEFINITIONS
"DM_PLUGIN_SUFFIX=\"${CMAKE_SHARED_LIBRARY_SUFFIX}\"")
+set_property(SOURCE dm_init.cpp APPEND PROPERTY COMPILE_DEFINITIONS
"DM_PLUGIN_SUFFIX=\"${CMAKE_SHARED_LIBRARY_SUFFIX}\"")
BRLCAD_ADDLIB(libdm "${LIBDM_SRCS}"
"librt;libbu;libpkg;${DM_EXTRA_LIBS};${PNG_LIBRARIES}")
set_target_properties(libdm PROPERTIES VERSION 20.0.1 SOVERSION 20)
Added: brlcad/branches/dm-fb-merge/src/libdm/dm_init.cpp
===================================================================
--- brlcad/branches/dm-fb-merge/src/libdm/dm_init.cpp
(rev 0)
+++ brlcad/branches/dm-fb-merge/src/libdm/dm_init.cpp 2020-04-21 18:11:41 UTC
(rev 75499)
@@ -0,0 +1,143 @@
+/* D M _ I N I T . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 2019-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file init.c
+ *
+ * NOTE: as this init is global to ALL applications before main(),
+ * care must be taken to not write to STDOUT or STDERR or app output
+ * may be corrupted, signals can be raised, or worse.
+ *
+ */
+
+#include "common.h"
+
+#include "bu/defines.h"
+#include "bu/app.h"
+#include "bu/dylib.h"
+#include "bu/file.h"
+#include "bu/vls.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "./include/private.h"
+
+static std::map<std::string, const struct dm *> dm_map;
+void *dm_backends;
+
+static std::set<void *> dm_handles;
+struct bu_vls dm_plugin_msgs = BU_VLS_INIT_ZERO;
+
+
+static void
+libdm_init(void)
+{
+ const char *ppath = bu_dir(NULL, 0, BU_DIR_LIBEXEC, "dm", NULL);
+ char **filenames;
+ const char *psymbol = "dm_plugin_info";
+ struct bu_vls plugin_pattern = BU_VLS_INIT_ZERO;
+ bu_vls_sprintf(&plugin_pattern, "*%s", DM_PLUGIN_SUFFIX);
+ size_t nfiles = bu_file_list(ppath, bu_vls_cstr(&plugin_pattern),
&filenames);
+ for (size_t i = 0; i < nfiles; i++) {
+ char pfile[MAXPATHLEN] = {0};
+ bu_dir(pfile, MAXPATHLEN, BU_DIR_LIBEXEC, "dm", filenames[i], NULL);
+ void *dl_handle, *info_val;
+ if (!(dl_handle = bu_dlopen(pfile, BU_RTLD_NOW))) {
+ const char * const error_msg = bu_dlerror();
+ if (error_msg)
+ bu_vls_printf(&dm_plugin_msgs, "%s\n", error_msg);
+
+ bu_vls_printf(&dm_plugin_msgs, "Unable to dynamically load '%s'
(skipping)\n", pfile);
+ continue;
+ }
+ info_val = bu_dlsym(dl_handle, psymbol);
+ const struct dm_plugin *(*plugin_info)() = (const struct dm_plugin
*(*)())(intptr_t)info_val;
+ if (!plugin_info) {
+ const char * const error_msg = bu_dlerror();
+
+ if (error_msg)
+ bu_vls_printf(&dm_plugin_msgs, "%s\n", error_msg);
+
+ bu_vls_printf(&dm_plugin_msgs, "Unable to load symbols from '%s'
(skipping)\n", pfile);
+ bu_vls_printf(&dm_plugin_msgs, "Could not find '%s' symbol in
plugin\n", psymbol);
+ bu_dlclose(dl_handle);
+ continue;
+ }
+
+ const struct dm_plugin *plugin = plugin_info();
+
+ if (!plugin || !plugin->p) {
+ bu_vls_printf(&dm_plugin_msgs, "Invalid plugin encountered from
'%s' (skipping)\n", pfile);
+ bu_dlclose(dl_handle);
+ continue;
+ }
+
+ const struct dm *d = plugin->p;
+ const char *dname = dm_get_name(d);
+ std::string key(dname);
+ if (dm_map.find(key) != dm_map.end()) {
+ bu_vls_printf(&dm_plugin_msgs, "Warning - file '%s' provides
backend '%s' but that backend has already been loaded, skipping\n", pfile,
dname);
+ bu_dlclose(dl_handle);
+ continue;
+ }
+ dm_handles.insert(dl_handle);
+ dm_map[key] = d;
+ }
+
+ dm_backends = (void *)&dm_map;
+}
+
+
+static void
+libdm_clear(void)
+{
+ dm_map.clear();
+ std::set<void *>::iterator h_it;
+ for (h_it = dm_handles.begin(); h_it != dm_handles.end(); h_it++) {
+ void *handle = *h_it;
+ bu_dlclose(handle);
+ }
+ dm_handles.clear();
+}
+
+
+struct libdm_initializer {
+ /* constructor */
+ libdm_initializer() {
+ libdm_init();
+ }
+ /* destructor */
+ ~libdm_initializer() {
+ libdm_clear();
+ }
+};
+
+static libdm_initializer LIBDM;
+
+
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
Property changes on: brlcad/branches/dm-fb-merge/src/libdm/dm_init.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Deleted: brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.c
===================================================================
--- brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.c 2020-04-21 17:16:59 UTC
(rev 75498)
+++ brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.c 2020-04-21 18:11:41 UTC
(rev 75499)
@@ -1,238 +0,0 @@
-#include "common.h"
-#include <string.h>
-
-#include "bu/app.h"
-#include "bu/dylib.h"
-#include "bu/file.h"
-#include "bu/log.h"
-#include "bu/ptbl.h"
-#include "bu/vls.h"
-
-#include "dm.h"
-#include "./include/private.h"
-
-int
-dm_load_backends(struct bu_ptbl *plugins, struct bu_ptbl *handles)
-{
- const char *ppath = bu_dir(NULL, 0, BU_DIR_LIBEXEC, "dm", NULL);
- char **filenames;
- const char *psymbol = "dm_plugin_info";
- struct bu_vls plugin_pattern = BU_VLS_INIT_ZERO;
- bu_vls_sprintf(&plugin_pattern, "*%s", DM_PLUGIN_SUFFIX);
- size_t nfiles = bu_file_list(ppath, bu_vls_cstr(&plugin_pattern),
&filenames);
- for (size_t i = 0; i < nfiles; i++) {
- char pfile[MAXPATHLEN] = {0};
- bu_dir(pfile, MAXPATHLEN, BU_DIR_LIBEXEC, "dm", filenames[i], NULL);
- void *dl_handle, *info_val;
- if (!(dl_handle = bu_dlopen(pfile, BU_RTLD_NOW))) {
- const char * const error_msg = bu_dlerror();
- if (error_msg)
- bu_log("%s\n", error_msg);
-
- bu_log("Unable to dynamically load '%s' (skipping)\n", pfile);
- continue;
- }
- if (handles) {
- bu_ptbl_ins(handles, (long *)dl_handle);
- }
- info_val = bu_dlsym(dl_handle, psymbol);
- const struct dm_plugin *(*plugin_info)() = (const struct dm_plugin
*(*)())(intptr_t)info_val;
- if (!plugin_info) {
- const char * const error_msg = bu_dlerror();
-
- if (error_msg)
- bu_log("%s\n", error_msg);
-
- bu_log("Unable to load symbols from '%s' (skipping)\n", pfile);
- bu_log("Could not find '%s' symbol in plugin\n", psymbol);
- continue;
- }
-
- const struct dm_plugin *plugin = plugin_info();
-
- if (!plugin || !plugin->p) {
- bu_log("Invalid plugin encountered from '%s' (skipping)\n", pfile);
- continue;
- }
-
- const struct dm *d = plugin->p;
- bu_ptbl_ins(plugins, (long *)d);
- }
-
- return BU_PTBL_LEN(plugins);
-}
-
-int
-dm_close_backends(struct bu_ptbl *handles)
-{
- int ret = 0;
- for (size_t i = 0; i < BU_PTBL_LEN(handles); i++) {
- if (bu_dlclose((void *)BU_PTBL_GET(handles, i))) {
- ret = 1;
- }
- }
-
- return ret;
-}
-
-
-struct dm *
-dm_popen(void *interp, const char *type, int argc, const char *argv[])
-{
- struct dm *dmp = DM_NULL;
-
- struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
- struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
- int dm_cnt = dm_load_backends(&plugins, &handles);
- if (!dm_cnt) {
- bu_log("No display manager implementations found!\n");
- return DM_NULL;
- }
-
- for (size_t i = 0; i < BU_PTBL_LEN(&plugins); i++) {
- const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, i);
- if (BU_STR_EQUIV(type, dm_get_name(d))) {
- dmp = d->i->dm_open(interp, argc, argv);
- break;
- }
- }
- bu_ptbl_free(&plugins);
-
- if (dm_close_backends(&handles)) {
- bu_log("bu_dlclose failed to unload plugins.\n");
- }
- bu_ptbl_free(&handles);
-
- return dmp;
-}
-
-
-void
-dm_list_backends(const char *separator)
-{
- struct bu_vls *list;
- BU_GET(list, struct bu_vls);
- bu_vls_init(list);
- bu_vls_trunc(list, 0);
-
- struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
- struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
- int dm_cnt = dm_load_backends(&plugins, &handles);
- if (!dm_cnt) {
- bu_log("No display manager implementations found!\n");
- return;
- }
-
- // We've got something, and may need a separator
- struct bu_vls sep = BU_VLS_INIT_ZERO;
- if (!separator) {
- bu_vls_sprintf(&sep, " ");
- } else {
- bu_vls_sprintf(&sep, "%s", separator);
- }
-
- for (size_t i = 0; i < BU_PTBL_LEN(&plugins); i++) {
- const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, i);
- if (strlen(bu_vls_cstr(list)) > 0) bu_vls_printf(list, "%s",
bu_vls_cstr(&sep));
- bu_vls_printf(list, "%s", dm_get_name(d));
- }
- bu_ptbl_free(&plugins);
-
- if (dm_close_backends(&handles)) {
- bu_log("bu_dlclose failed to unload plugins.\n");
- }
- bu_ptbl_free(&handles);
-
- bu_log("%s\n", bu_vls_cstr(list));
- bu_vls_free(list);
- BU_PUT(list, struct bu_vls);
-}
-
-int
-dm_valid_type(const char *name, const char *dpy_string)
-{
- struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
- struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
- int dm_cnt = dm_load_backends(&plugins, &handles);
- if (!dm_cnt) {
- bu_log("No display manager implementations found!\n");
- return 0;
- }
-
- int is_valid = 0;
-
- for (size_t i = 0; i < BU_PTBL_LEN(&plugins); i++) {
- const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, i);
- if (BU_STR_EQUIV(name, dm_get_name(d))) {
- if (d->i->dm_viable(dpy_string) != 1) {
- bu_log("WARNING: found matching plugin %s, but viability test
failed - skipping.\n", dm_get_name(d));
- } else {
- is_valid = 1;
- break;
- }
- }
- }
- bu_ptbl_free(&plugins);
- if (dm_close_backends(&handles)) {
- bu_log("bu_dlclose failed to unload plugins.\n");
- }
- bu_ptbl_free(&handles);
-
- return is_valid;
-}
-
-/** dm_recommend_type determines what mged will normally
- * use as the default display manager
- */
-const char *
-dm_recommend_type(const char *dpy_string)
-{
- static const char *priority_list[] = {"osgl", "wgl", "ogl", "X", "tk",
"nu"};
-
- struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
- struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
- int dm_cnt = dm_load_backends(&plugins, &handles);
- if (!dm_cnt) {
- bu_log("No display manager implementations found!\n");
- return NULL;
- }
-
- const char *ret = NULL;
-
- int i = 0;
- const char *b = priority_list[i];
- while (!BU_STR_EQUAL(b, "nu")) {
- for (size_t j = 0; j < BU_PTBL_LEN(&plugins); j++) {
- const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, j);
- if (BU_STR_EQUIV(b, dm_get_name(d))) {
- if (d->i->dm_viable(dpy_string) == 1) {
- ret = b;
- break;
- }
- }
- }
- if (ret) {
- break;
- }
- i++;
- b = priority_list[i];
- }
-
- bu_ptbl_free(&plugins);
- if (dm_close_backends(&handles)) {
- bu_log("bu_dlclose failed to unload plugins.\n");
- }
- bu_ptbl_free(&handles);
-
- return (ret) ? ret : b;
-}
-
-/*
- * Local Variables:
- * tab-width: 8
- * mode: C
- * indent-tabs-mode: t
- * c-file-style: "stroustrup"
- * End:
- * ex: shiftwidth=4 tabstop=8
- */
Copied: brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.cpp (from rev 75498,
brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.c)
===================================================================
--- brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.cpp
(rev 0)
+++ brlcad/branches/dm-fb-merge/src/libdm/dm_plugins.cpp 2020-04-21
18:11:41 UTC (rev 75499)
@@ -0,0 +1,227 @@
+#include "common.h"
+#include <string.h>
+
+#include "bu/app.h"
+#include "bu/dylib.h"
+#include "bu/file.h"
+#include "bu/log.h"
+#include "bu/ptbl.h"
+#include "bu/vls.h"
+
+#include "dm.h"
+#include "./include/private.h"
+
+int
+dm_load_backends(struct bu_ptbl *plugins, struct bu_ptbl *handles)
+{
+ const char *ppath = bu_dir(NULL, 0, BU_DIR_LIBEXEC, "dm", NULL);
+ char **filenames;
+ const char *psymbol = "dm_plugin_info";
+ struct bu_vls plugin_pattern = BU_VLS_INIT_ZERO;
+ bu_vls_sprintf(&plugin_pattern, "*%s", DM_PLUGIN_SUFFIX);
+ size_t nfiles = bu_file_list(ppath, bu_vls_cstr(&plugin_pattern),
&filenames);
+ for (size_t i = 0; i < nfiles; i++) {
+ char pfile[MAXPATHLEN] = {0};
+ bu_dir(pfile, MAXPATHLEN, BU_DIR_LIBEXEC, "dm", filenames[i], NULL);
+ void *dl_handle, *info_val;
+ if (!(dl_handle = bu_dlopen(pfile, BU_RTLD_NOW))) {
+ const char * const error_msg = bu_dlerror();
+ if (error_msg)
+ bu_log("%s\n", error_msg);
+
+ bu_log("Unable to dynamically load '%s' (skipping)\n", pfile);
+ continue;
+ }
+ if (handles) {
+ bu_ptbl_ins(handles, (long *)dl_handle);
+ }
+ info_val = bu_dlsym(dl_handle, psymbol);
+ const struct dm_plugin *(*plugin_info)() = (const struct dm_plugin
*(*)())(intptr_t)info_val;
+ if (!plugin_info) {
+ const char * const error_msg = bu_dlerror();
+
+ if (error_msg)
+ bu_log("%s\n", error_msg);
+
+ bu_log("Unable to load symbols from '%s' (skipping)\n", pfile);
+ bu_log("Could not find '%s' symbol in plugin\n", psymbol);
+ continue;
+ }
+
+ const struct dm_plugin *plugin = plugin_info();
+
+ if (!plugin || !plugin->p) {
+ bu_log("Invalid plugin encountered from '%s' (skipping)\n", pfile);
+ continue;
+ }
+
+ const struct dm *d = plugin->p;
+ bu_ptbl_ins(plugins, (long *)d);
+ }
+
+ return BU_PTBL_LEN(plugins);
+}
+
+int
+dm_close_backends(struct bu_ptbl *handles)
+{
+ int ret = 0;
+ for (size_t i = 0; i < BU_PTBL_LEN(handles); i++) {
+ if (bu_dlclose((void *)BU_PTBL_GET(handles, i))) {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+
+struct dm *
+dm_popen(void *interp, const char *type, int argc, const char *argv[])
+{
+ struct dm *dmp = DM_NULL;
+
+ struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
+ struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
+ int dm_cnt = dm_load_backends(&plugins, &handles);
+ if (!dm_cnt) {
+ bu_log("No display manager implementations found!\n");
+ return DM_NULL;
+ }
+
+ for (size_t i = 0; i < BU_PTBL_LEN(&plugins); i++) {
+ const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, i);
+ if (BU_STR_EQUIV(type, dm_get_name(d))) {
+ dmp = d->i->dm_open(interp, argc, argv);
+ break;
+ }
+ }
+ bu_ptbl_free(&plugins);
+
+ if (dm_close_backends(&handles)) {
+ bu_log("bu_dlclose failed to unload plugins.\n");
+ }
+ bu_ptbl_free(&handles);
+
+ return dmp;
+}
+
+
+void
+dm_list_backends(const char *separator)
+{
+ struct bu_vls *list;
+ BU_GET(list, struct bu_vls);
+ bu_vls_init(list);
+ bu_vls_trunc(list, 0);
+
+ // We've got something, and may need a separator
+ struct bu_vls sep = BU_VLS_INIT_ZERO;
+ if (!separator) {
+ bu_vls_sprintf(&sep, " ");
+ } else {
+ bu_vls_sprintf(&sep, "%s", separator);
+ }
+
+ std::map<std::string, const struct dm *> *dmb = (std::map<std::string,
const struct dm *> *)dm_backends;
+ std::map<std::string, const struct dm *>::iterator d_it;
+ for (d_it = dmb->begin(); d_it != dmb->end(); d_it++) {
+ std::string key = d_it->first;
+ const struct dm *d = d_it->second;
+ if (strlen(bu_vls_cstr(list)) > 0) bu_vls_printf(list, "%s",
bu_vls_cstr(&sep));
+ bu_vls_printf(list, "%s: %s", key.c_str(), dm_get_name(d));
+ }
+
+ bu_log("%s\n", bu_vls_cstr(list));
+ bu_vls_free(list);
+ BU_PUT(list, struct bu_vls);
+}
+
+int
+dm_valid_type(const char *name, const char *dpy_string)
+{
+ struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
+ struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
+ int dm_cnt = dm_load_backends(&plugins, &handles);
+ if (!dm_cnt) {
+ bu_log("No display manager implementations found!\n");
+ return 0;
+ }
+
+ int is_valid = 0;
+
+ for (size_t i = 0; i < BU_PTBL_LEN(&plugins); i++) {
+ const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, i);
+ if (BU_STR_EQUIV(name, dm_get_name(d))) {
+ if (d->i->dm_viable(dpy_string) != 1) {
+ bu_log("WARNING: found matching plugin %s, but viability test
failed - skipping.\n", dm_get_name(d));
+ } else {
+ is_valid = 1;
+ break;
+ }
+ }
+ }
+ bu_ptbl_free(&plugins);
+ if (dm_close_backends(&handles)) {
+ bu_log("bu_dlclose failed to unload plugins.\n");
+ }
+ bu_ptbl_free(&handles);
+
+ return is_valid;
+}
+
+/** dm_recommend_type determines what mged will normally
+ * use as the default display manager
+ */
+const char *
+dm_recommend_type(const char *dpy_string)
+{
+ static const char *priority_list[] = {"osgl", "wgl", "ogl", "X", "tk",
"nu"};
+
+ struct bu_ptbl plugins = BU_PTBL_INIT_ZERO;
+ struct bu_ptbl handles = BU_PTBL_INIT_ZERO;
+ int dm_cnt = dm_load_backends(&plugins, &handles);
+ if (!dm_cnt) {
+ bu_log("No display manager implementations found!\n");
+ return NULL;
+ }
+
+ const char *ret = NULL;
+
+ int i = 0;
+ const char *b = priority_list[i];
+ while (!BU_STR_EQUAL(b, "nu")) {
+ for (size_t j = 0; j < BU_PTBL_LEN(&plugins); j++) {
+ const struct dm *d = (const struct dm *)BU_PTBL_GET(&plugins, j);
+ if (BU_STR_EQUIV(b, dm_get_name(d))) {
+ if (d->i->dm_viable(dpy_string) == 1) {
+ ret = b;
+ break;
+ }
+ }
+ }
+ if (ret) {
+ break;
+ }
+ i++;
+ b = priority_list[i];
+ }
+
+ bu_ptbl_free(&plugins);
+ if (dm_close_backends(&handles)) {
+ bu_log("bu_dlclose failed to unload plugins.\n");
+ }
+ bu_ptbl_free(&handles);
+
+ return (ret) ? ret : b;
+}
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Modified: brlcad/branches/dm-fb-merge/src/libdm/include/private.h
===================================================================
--- brlcad/branches/dm-fb-merge/src/libdm/include/private.h 2020-04-21
17:16:59 UTC (rev 75498)
+++ brlcad/branches/dm-fb-merge/src/libdm/include/private.h 2020-04-21
18:11:41 UTC (rev 75499)
@@ -28,6 +28,11 @@
#ifndef DM_PRIVATE_H
#define DM_PRIVATE_H
+/* Opaque container that holds the set of available libdm
+ * backend implementations. This is initialized at startup
+ * and it's contents are cleared at the end by dm_init.cpp */
+extern void *dm_backends;
+
#include <limits.h> /* For INT_MAX */
#include <stdlib.h>
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits