Revision: 75282
http://sourceforge.net/p/brlcad/code/75282
Author: starseeker
Date: 2020-04-07 13:39:24 +0000 (Tue, 07 Apr 2020)
Log Message:
-----------
Push the I/O handler functions up into libtclcad, adding function pointer slots
for them in struct ged. Working to hide the details of I/O channel setup
inside the libged library.
Modified Paths:
--------------
brlcad/trunk/include/ged/defines.h
brlcad/trunk/include/tclcad.h
brlcad/trunk/src/libged/ged_private.h
brlcad/trunk/src/libged/ged_util.c
brlcad/trunk/src/libged/rt.c
brlcad/trunk/src/libged/rtcheck.c
brlcad/trunk/src/libged/rtwizard.c
brlcad/trunk/src/libtclcad/tclcad_obj.c
brlcad/trunk/src/mged/setup.c
Modified: brlcad/trunk/include/ged/defines.h
===================================================================
--- brlcad/trunk/include/ged/defines.h 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/include/ged/defines.h 2020-04-07 13:39:24 UTC (rev 75282)
@@ -171,6 +171,9 @@
int gd_shaded_mode; /**< @brief 1
- draw bots shaded by default */
};
+
+typedef void (*ged_io_handler_callback_t)(void *, int);
+
struct ged_cmd;
/* struct details are private - use accessor functions to manipulate */
@@ -215,6 +218,10 @@
/* FIXME -- this ugly hack needs to die. the result string should be
stored before the call. */
int ged_internal_call;
+ /* Handler functions for I/O communication with asynchronous subprocess
commands */
+ void (*ged_create_io_handler)(void **chan, struct bu_process *p, int fd,
int mode, void *data, ged_io_handler_callback_t callback);
+ void (*ged_delete_io_handler)(void *interp, void *chan, struct bu_process
*p, int fd, void *data, ged_io_handler_callback_t callback);
+
/* FOR LIBGED INTERNAL USE */
struct ged_cmd *cmds;
int (*add)(struct ged *gedp, const struct ged_cmd *cmd);
@@ -226,7 +233,6 @@
void *ged_interp; /* Temporary - do not rely on when designing new
functionality */
db_search_callback_t ged_interp_eval; /* FIXME: broke the rule written on
the previous line */
-
/* Interface to LIBDM */
int ged_dm_width;
int ged_dm_height;
Modified: brlcad/trunk/include/tclcad.h
===================================================================
--- brlcad/trunk/include/tclcad.h 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/include/tclcad.h 2020-04-07 13:39:24 UTC (rev 75282)
@@ -471,7 +471,18 @@
*/
TCLCAD_EXPORT extern int tclcad_init(Tcl_Interp *interp, int init_gui, struct
bu_vls *tlog);
+/**
+ * Create Tcl specific I/O handlers
+ */
+TCLCAD_EXPORT void
+tclcad_create_io_handler(void **chan, struct bu_process *p, int fd, int mode,
void *data, ged_io_handler_callback_t callback);
+/**
+ * Delete Tcl specific I/O handlers
+ */
+TCLCAD_EXPORT void
+tclcad_delete_io_handler(void *interp, void *chan, struct bu_process *p, int
fd, void *data, ged_io_handler_callback_t callback);
+
__END_DECLS
#endif /* TCLCAD_H */
Modified: brlcad/trunk/src/libged/ged_private.h
===================================================================
--- brlcad/trunk/src/libged/ged_private.h 2020-04-07 12:49:21 UTC (rev
75281)
+++ brlcad/trunk/src/libged/ged_private.h 2020-04-07 13:39:24 UTC (rev
75282)
@@ -608,15 +608,6 @@
extern int
_ged_sort_existing_objs(struct ged *gedp, int argc, const char *argv[], struct
directory **dpa);
-
-typedef void (*io_handler_callback_t)(void *, int);
-extern void
-_ged_create_io_handler(void **chan, struct bu_process *p, int fd, int mode,
void *data, io_handler_callback_t callback);
-extern void
-_ged_delete_io_handler(void *interp, void *chan, struct bu_process *p, int fd,
void *data, io_handler_callback_t callback);
-
-
-
/* Ideally all of this could be in facetize.cpp, but the open() calls
* used by the logging routines are problematic in C++ with Visual C++. */
struct _ged_facetize_opts {
Modified: brlcad/trunk/src/libged/ged_util.c
===================================================================
--- brlcad/trunk/src/libged/ged_util.c 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/src/libged/ged_util.c 2020-04-07 13:39:24 UTC (rev 75282)
@@ -504,52 +504,6 @@
}
-
-/* Wrappers for setting up/tearing down IO handler */
-#ifndef _WIN32
-void
-_ged_create_io_handler(void **UNUSED(chan), struct bu_process *p, int fd, int
mode, void *data, io_handler_callback_t callback)
-{
- int *fdp;
- if (!p) return;
- fdp = (int *)bu_process_fd(p, fd);
- Tcl_CreateFileHandler(*fdp, mode, callback, (ClientData)data);
-}
-
-void
-_ged_delete_io_handler(void *UNUSED(interp), void *UNUSED(chan), struct
bu_process *p, int fd, void *UNUSED(data), io_handler_callback_t
UNUSED(callback))
-{
- int *fdp;
- if (!p) return;
- fdp = (int *)bu_process_fd(p, fd);
- Tcl_DeleteFileHandler(*fdp);
- close(*fdp);
-}
-
-#else
-void
-_ged_create_io_handler(void **chan, struct bu_process *p, int fd, int mode,
void *data, io_handler_callback_t callback)
-{
- HANDLE *fdp;
- if (!chan || !p) return;
- fdp = (HANDLE *)bu_process_fd(p, fd);
- (*chan) = (void *)Tcl_MakeFileChannel(*fdp, mode);
- Tcl_CreateChannelHandler((Tcl_Channel)(*chan), mode, callback,
(ClientData)data);
-}
-
-void
-_ged_delete_io_handler(void *interp, void *chan, struct bu_process *p, int fd,
void *data, io_handler_callback_t callback)
-{
- HANDLE *fdp;
- Tcl_Interp *tcl_interp;
- if (!chan || !p) return;
- tcl_interp = (Tcl_Interp *)interp;
- fdp = (HANDLE *)bu_process_fd(p, fd);
- Tcl_DeleteChannelHandler((Tcl_Channel)chan, callback, (ClientData)data);
- Tcl_Close(tcl_interp, (Tcl_Channel)chan);
-}
-#endif
-
/*
* Local Variables:
* mode: C
Modified: brlcad/trunk/src/libged/rt.c
===================================================================
--- brlcad/trunk/src/libged/rt.c 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/src/libged/rt.c 2020-04-07 13:39:24 UTC (rev 75282)
@@ -177,12 +177,12 @@
if (read_failed) {
int aborted;
- /* Done watching for output, undo Tcl hooks. TODO - need to push the
- * Tcl specific aspects of this up stack... */
- _ged_delete_io_handler(drcdp->gedp->ged_interp, run_rtp->chan,
- run_rtp->p, BU_PROCESS_STDERR, (void *)drcdp,
- _ged_rt_output_handler);
-
+ /* Done watching for output, undo subprocess I/O hooks. */
+ if (drcdp->gedp->ged_delete_io_handler) {
+ (*drcdp->gedp->ged_delete_io_handler)(drcdp->gedp->ged_interp,
run_rtp->chan,
+ run_rtp->p, BU_PROCESS_STDERR, (void *)drcdp,
+ _ged_rt_output_handler);
+ }
/* Either EOF has been sent or there was a read error.
* there is no need to block indefinitely */
retcode = bu_process_wait(&aborted, run_rtp->p, 120);
@@ -252,10 +252,10 @@
drcdp->gedp = gedp;
drcdp->rrtp = run_rtp;
- /* Set up Tcl hooks so the parent Tcl process knows to watch for output.
- * TODO - need to push the Tcl specific aspects of this up stack... */
- _ged_create_io_handler(&(run_rtp->chan), p, BU_PROCESS_STDERR,
TCL_READABLE, (void *)drcdp, _ged_rt_output_handler);
-
+ /* If we know how, set up hooks so the parent process knows to watch for
output. */
+ if (gedp->ged_create_io_handler) {
+ (*gedp->ged_create_io_handler)(&(run_rtp->chan), p, BU_PROCESS_STDERR,
TCL_READABLE, (void *)drcdp, _ged_rt_output_handler);
+ }
return GED_OK;
}
Modified: brlcad/trunk/src/libged/rtcheck.c
===================================================================
--- brlcad/trunk/src/libged/rtcheck.c 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/src/libged/rtcheck.c 2020-04-07 13:39:24 UTC (rev 75282)
@@ -82,14 +82,15 @@
{
int retcode;
- _ged_delete_io_handler(rtcp->gedp->ged_interp, rtcp->rrtp->chan,
- rtcp->rrtp->p, BU_PROCESS_STDOUT, (void *)rtcp,
- rtcheck_vector_handler);
+ if (rtcp->gedp->ged_delete_io_handler) {
+ (*rtcp->gedp->ged_delete_io_handler)(rtcp->gedp->ged_interp,
rtcp->rrtp->chan,
+ rtcp->rrtp->p, BU_PROCESS_STDOUT, (void *)rtcp,
+ rtcheck_vector_handler);
+ (*rtcp->gedp->ged_delete_io_handler)(rtcp->gedp->ged_interp, rtcp->chan,
+ rtcp->p, BU_PROCESS_STDERR, (void *)rtcp,
+ rtcheck_output_handler);
+ }
- _ged_delete_io_handler(rtcp->gedp->ged_interp, rtcp->chan,
- rtcp->p, BU_PROCESS_STDERR, (void *)rtcp,
- rtcheck_output_handler);
-
bu_process_close(rtcp->rrtp->p, BU_PROCESS_STDOUT);
/* wait for the forked process */
@@ -296,11 +297,15 @@
BU_GET(rtcp->rrtp, struct ged_subprocess);
rtcp->rrtp->p = p;
rtcp->rrtp->aborted = 0;
- _ged_create_io_handler(&(rtcp->rrtp->chan), p, BU_PROCESS_STDOUT,
TCL_READABLE, (void *)rtcp, rtcheck_vector_handler);
+ if (gedp->ged_create_io_handler) {
+ (*gedp->ged_create_io_handler)(&(rtcp->rrtp->chan), p,
BU_PROCESS_STDOUT, TCL_READABLE, (void *)rtcp, rtcheck_vector_handler);
+ }
BU_LIST_INIT(&rtcp->rrtp->l);
BU_LIST_APPEND(&gedp->gd_headSubprocess.l, &rtcp->rrtp->l);
- _ged_create_io_handler(&(rtcp->chan), p, BU_PROCESS_STDERR, TCL_READABLE,
(void *)rtcp, rtcheck_output_handler);
+ if (gedp->ged_create_io_handler) {
+ (*gedp->ged_create_io_handler)(&(rtcp->chan), p, BU_PROCESS_STDERR,
TCL_READABLE, (void *)rtcp, rtcheck_output_handler);
+ }
bu_free(gd_rt_cmd, "free gd_rt_cmd");
Modified: brlcad/trunk/src/libged/rtwizard.c
===================================================================
--- brlcad/trunk/src/libged/rtwizard.c 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/src/libged/rtwizard.c 2020-04-07 13:39:24 UTC (rev 75282)
@@ -74,7 +74,9 @@
drcdp->gedp = gedp;
drcdp->rrtp = run_rtp;
- _ged_create_io_handler(&(run_rtp->chan), p, BU_PROCESS_STDERR,
TCL_READABLE, (void *)drcdp, _ged_rt_output_handler);
+ if (gedp->ged_create_io_handler) {
+ (*gedp->ged_create_io_handler)(&(run_rtp->chan), p, BU_PROCESS_STDERR,
TCL_READABLE, (void *)drcdp, _ged_rt_output_handler);
+ }
return GED_OK;
}
Modified: brlcad/trunk/src/libtclcad/tclcad_obj.c
===================================================================
--- brlcad/trunk/src/libtclcad/tclcad_obj.c 2020-04-07 12:49:21 UTC (rev
75281)
+++ brlcad/trunk/src/libtclcad/tclcad_obj.c 2020-04-07 13:39:24 UTC (rev
75282)
@@ -51,6 +51,7 @@
#include "rt/geom.h"
#include "wdb.h"
#include "raytrace.h"
+#include "ged.h"
#include "tclcad.h"
#include "rt/solid.h"
@@ -57,7 +58,6 @@
#include "dm.h"
#include "dm/bview.h"
-#include "ged.h"
#include "icv/io.h"
#include "icv/ops.h"
#include "icv/crop.h"
@@ -1521,7 +1521,6 @@
return TCL_OK;
}
-
/**
* @brief create the Tcl command for to_open
*
@@ -1693,6 +1692,52 @@
}
+/* Wrappers for setting up/tearing down IO handler */
+#ifndef _WIN32
+void
+tclcad_create_io_handler(void **UNUSED(chan), struct bu_process *p, int fd,
int mode, void *data, ged_io_handler_callback_t callback)
+{
+ int *fdp;
+ if (!p) return;
+ fdp = (int *)bu_process_fd(p, fd);
+ Tcl_CreateFileHandler(*fdp, mode, callback, (ClientData)data);
+}
+
+void
+tclcad_delete_io_handler(void *UNUSED(interp), void *UNUSED(chan), struct
bu_process *p, int fd, void *UNUSED(data), ged_io_handler_callback_t
UNUSED(callback))
+{
+ int *fdp;
+ if (!p) return;
+ fdp = (int *)bu_process_fd(p, fd);
+ Tcl_DeleteFileHandler(*fdp);
+ close(*fdp);
+}
+
+#else
+void
+tclcad_create_io_handler(void **chan, struct bu_process *p, int fd, int mode,
void *data, ged_io_handler_callback_t callback)
+{
+ HANDLE *fdp;
+ if (!chan || !p) return;
+ fdp = (HANDLE *)bu_process_fd(p, fd);
+ (*chan) = (void *)Tcl_MakeFileChannel(*fdp, mode);
+ Tcl_CreateChannelHandler((Tcl_Channel)(*chan), mode, callback,
(ClientData)data);
+}
+
+void
+tclcad_delete_io_handler(void *interp, void *chan, struct bu_process *p, int
fd, void *data, ged_io_handler_callback_t callback)
+{
+ HANDLE *fdp;
+ Tcl_Interp *tcl_interp;
+ if (!chan || !p) return;
+ tcl_interp = (Tcl_Interp *)interp;
+ fdp = (HANDLE *)bu_process_fd(p, fd);
+ Tcl_DeleteChannelHandler((Tcl_Channel)chan, callback, (ClientData)data);
+ Tcl_Close(tcl_interp, (Tcl_Channel)chan);
+}
+#endif
+
+
/**
* @brief
* A TCL interface to wdb_fopen() and wdb_dbopen().
@@ -1768,6 +1813,10 @@
}
gedp->ged_interp = (void *)interp;
+ /* Set the Tcl specific I/O handlers for asynchronous subprocess I/O */
+ gedp->ged_create_io_handler = &tclcad_create_io_handler;
+ gedp->ged_delete_io_handler = &tclcad_delete_io_handler;
+
/* initialize tclcad_obj */
BU_ALLOC(top, struct tclcad_obj);
top->to_interp = interp;
Modified: brlcad/trunk/src/mged/setup.c
===================================================================
--- brlcad/trunk/src/mged/setup.c 2020-04-07 12:49:21 UTC (rev 75281)
+++ brlcad/trunk/src/mged/setup.c 2020-04-07 13:39:24 UTC (rev 75282)
@@ -474,6 +474,8 @@
mged_global_variable_setup(*interpreter);
mged_variable_setup(*interpreter);
GEDP->ged_interp = (void *)*interpreter;
+ GEDP->ged_create_io_handler = &tclcad_create_io_handler;
+ GEDP->ged_delete_io_handler = &tclcad_delete_io_handler;
GEDP->ged_interp_eval = &mged_db_search_callback;
/* Tcl needs to write nulls onto subscripted variable names */
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