Revision: 77451
http://sourceforge.net/p/brlcad/code/77451
Author: starseeker
Date: 2020-10-15 13:44:58 +0000 (Thu, 15 Oct 2020)
Log Message:
-----------
Start working on per-process channel storage for Windows
Modified Paths:
--------------
brlcad/trunk/include/tclcad.h
brlcad/trunk/src/libtclcad/commands.cpp
brlcad/trunk/src/mged/mged.c
Modified: brlcad/trunk/include/tclcad.h
===================================================================
--- brlcad/trunk/include/tclcad.h 2020-10-15 12:58:52 UTC (rev 77450)
+++ brlcad/trunk/include/tclcad.h 2020-10-15 13:44:58 UTC (rev 77451)
@@ -518,13 +518,16 @@
* Tcl specific I/O handlers
*/
struct tclcad_io_data {
- Tcl_Channel chan_stdin;
- Tcl_Channel chan_stdout;
- Tcl_Channel chan_stderr;
Tcl_Interp *interp;
int io_mode;
+ void *state;
};
+TCLCAD_EXPORT struct tclcad_io_data *
+tclcad_create_io_data();
TCLCAD_EXPORT void
+tclcad_destroy_io_data(struct tclcad_io_data *d);
+
+TCLCAD_EXPORT void
tclcad_create_io_handler(struct ged_subprocess *p, bu_process_io_t d,
ged_io_func_t callback, void *data);
TCLCAD_EXPORT void
tclcad_delete_io_handler(struct ged_subprocess *p, bu_process_io_t d);
Modified: brlcad/trunk/src/libtclcad/commands.cpp
===================================================================
--- brlcad/trunk/src/libtclcad/commands.cpp 2020-10-15 12:58:52 UTC (rev
77450)
+++ brlcad/trunk/src/libtclcad/commands.cpp 2020-10-15 13:44:58 UTC (rev
77451)
@@ -31,6 +31,8 @@
#include "common.h"
+#include <map>
+
extern "C" {
#include <stdlib.h>
#include <ctype.h>
@@ -87,6 +89,29 @@
#include "./view/view.h"
}
+struct tclcad_process_channels {
+ Tcl_Channel cstdin;
+ Tcl_Channel cstdout;
+ Tcl_Channel cstderr;
+};
+
+struct tclcad_io_data *
+tclcad_create_io_data()
+{
+ struct tclcad_io_data *d;
+ BU_GET(d, struct tclcad_io_data);
+ d->state = new std::map<struct ged_subprocess *, struct
tclcad_process_channels *>;
+ return d;
+}
+
+TCLCAD_EXPORT void
+tclcad_destroy_io_data(struct tclcad_io_data *d)
+{
+ std::map<struct ged_subprocess *, struct tclcad_process_channels *> *s =
(std::map<struct ged_subprocess *, struct tclcad_process_channels *> *)d->state;
+ delete s;
+ BU_PUT(d, struct tclcad_io_data);
+}
+
HIDDEN int to_base2local(struct ged *gedp,
int argc,
const char *argv[],
@@ -1146,7 +1171,8 @@
}
if (top->to_gedp->ged_io_data) {
struct tclcad_io_data *t_iod = (struct tclcad_io_data
*)top->to_gedp->ged_io_data;
- BU_PUT(t_iod, struct tclcad_io_data);
+ tclcad_destroy_io_data(t_iod);
+ top->to_gedp->ged_io_data = NULL;
}
// Got the libtclcad cleanup done, have libged do its up.
@@ -1220,25 +1246,37 @@
if (!p || !p->p || !p->gedp || !p->gedp->ged_io_data)
return;
struct tclcad_io_data *t_iod = (struct tclcad_io_data
*)p->gedp->ged_io_data;
+ std::map<struct ged_subprocess *, struct tclcad_process_channels *> *pmap
= (std::map<struct ged_subprocess *, struct tclcad_process_channels *>
*)t_iod->state;
+ struct tclcad_process_channels *pchan = NULL;
+ if (pmap->find(p) == pmap->end()) {
+ BU_GET(pchan, struct tclcad_process_channels);
+ pchan->cstdin = NULL;
+ pchan->cstdout = NULL;
+ pchan->cstderr = NULL;
+ pmap[p] = pchan;
+ } else {
+ pchan = pmap[p];
+ }
+
HANDLE *fdp = (HANDLE *)bu_process_fd(p->p, d);
if (fdp) {
switch (d) {
case BU_PROCESS_STDIN:
- if (!t_iod->chan_stdin) {
- t_iod->chan_stdin = Tcl_MakeFileChannel(*fdp,
t_iod->io_mode);
- Tcl_CreateChannelHandler(t_iod->chan_stdin, t_iod->io_mode,
callback, (ClientData)data);
+ if (!pchan->cstdin) {
+ pchan->cstdin = Tcl_MakeFileChannel(*fdp, t_iod->io_mode);
+ Tcl_CreateChannelHandler(pchan->cstdin, t_iod->io_mode,
callback, (ClientData)data);
}
break;
case BU_PROCESS_STDOUT:
- if (!t_iod->chan_stdout) {
- t_iod->chan_stdout = Tcl_MakeFileChannel(*fdp,
t_iod->io_mode);
- Tcl_CreateChannelHandler(t_iod->chan_stdout,
t_iod->io_mode, callback, (ClientData)data);
+ if (!pchan->cstdout) {
+ pchan->cstdout = Tcl_MakeFileChannel(*fdp, t_iod->io_mode);
+ Tcl_CreateChannelHandler(pchan->cstdout, t_iod->io_mode,
callback, (ClientData)data);
}
break;
case BU_PROCESS_STDERR:
- if (!t_iod->chan_stderr) {
- t_iod->chan_stderr = Tcl_MakeFileChannel(*fdp,
t_iod->io_mode);
- Tcl_CreateChannelHandler(t_iod->chan_stderr,
t_iod->io_mode, callback, (ClientData)data);
+ if (!pchan->cstderr) {
+ pchan->cstderr = Tcl_MakeFileChannel(*fdp, t_iod->io_mode);
+ Tcl_CreateChannelHandler(pchan->cstderr, t_iod->io_mode,
callback, (ClientData)data);
}
break;
}
@@ -1252,26 +1290,38 @@
if (!p || !p->p || !p->gedp || !p->gedp->ged_io_data)
return;
struct tclcad_io_data *t_iod = (struct tclcad_io_data
*)p->gedp->ged_io_data;
+ std::map<struct ged_subprocess *, struct tclcad_process_channels *> *pmap
= (std::map<struct ged_subprocess *, struct tclcad_process_channels *>
*)t_iod->state;
+ struct tclcad_process_channels *pchan = NULL;
+ if (!pmap || pmap->find(p) == pmap->end()) {
+ return;
+ }
+ pchan = pmap[p];
+ if (!pchan->cstdin && !pchan->cstdout && !pchan->cstdout) {
+ // All subprocess channels destroyed; we're done with the I/O from this
subprocess, clean up
+ BU_PUT(pchan, struct tclcad_process_channels);
+ pmap.erase(p);
+ }
+
switch (d) {
case BU_PROCESS_STDIN:
- if (t_iod->chan_stdin) {
- Tcl_DeleteChannelHandler(t_iod->chan_stdin, NULL,
(ClientData)NULL);
- Tcl_Close(t_iod->interp, t_iod->chan_stdin);
- t_iod->chan_stdin = NULL;
+ if (pchan->cstdin) {
+ Tcl_DeleteChannelHandler(pchan->cstdin, NULL, (ClientData)NULL);
+ Tcl_Close(t_iod->interp, pchan->cstdin);
+ pchan->cstdin = NULL;
}
break;
case BU_PROCESS_STDOUT:
- if (t_iod->chan_stdout) {
- Tcl_DeleteChannelHandler(t_iod->chan_stdout, NULL,
(ClientData)NULL);
- Tcl_Close(t_iod->interp, t_iod->chan_stdout);
- t_iod->chan_stdout = NULL;
+ if (pchan->cstdout) {
+ Tcl_DeleteChannelHandler(pchan->cstdout, NULL,
(ClientData)NULL);
+ Tcl_Close(t_iod->interp, pchan->cstdout);
+ pchan->cstdout = NULL;
}
break;
case BU_PROCESS_STDERR:
- if (t_iod->chan_stderr) {
- Tcl_DeleteChannelHandler(t_iod->chan_stderr, NULL,
(ClientData)NULL);
- Tcl_Close(t_iod->interp, t_iod->chan_stderr);
- t_iod->chan_stderr = NULL;
+ if (pchan->cstderr) {
+ Tcl_DeleteChannelHandler(pchan->cstderr, NULL,
(ClientData)NULL);
+ Tcl_Close(t_iod->interp, pchan->cstderr);
+ pchan->cstderr = NULL;
}
break;
}
@@ -1355,8 +1405,7 @@
gedp->ged_interp = (void *)interp;
/* Set the Tcl specific I/O handlers for asynchronous subprocess I/O */
- struct tclcad_io_data *t_iod;
- BU_GET(t_iod, struct tclcad_io_data);
+ struct tclcad_io_data *t_iod = tclcad_create_io_data();
t_iod->io_mode = TCL_READABLE;
t_iod->interp = interp;
gedp->ged_io_data = (void *)t_iod;
Modified: brlcad/trunk/src/mged/mged.c
===================================================================
--- brlcad/trunk/src/mged/mged.c 2020-10-15 12:58:52 UTC (rev 77450)
+++ brlcad/trunk/src/mged/mged.c 2020-10-15 13:44:58 UTC (rev 77451)
@@ -2507,8 +2507,9 @@
Tcl_Release((ClientData)INTERP);
ged_close(GEDP);
- if (GEDP->ged_io_data)
- BU_PUT(GEDP->ged_io_data, struct tclcad_io_data);
+ if (GEDP->ged_io_data) {
+ tclcad_destroy_io_data((struct tclcad_io_data *)GEDP->ged_io_data);
+ }
if (GEDP)
BU_PUT(GEDP, struct ged);
@@ -2804,8 +2805,7 @@
GEDP->ged_delete_io_handler = &tclcad_delete_io_handler;
GEDP->ged_interp = (void *)interpreter;
GEDP->ged_interp_eval = &mged_db_search_callback;
- struct tclcad_io_data *t_iod;
- BU_GET(t_iod, struct tclcad_io_data);
+ struct tclcad_io_data *t_iod = tclcad_create_io_data();
t_iod->io_mode = TCL_READABLE;
t_iod->interp = interpreter;
GEDP->ged_io_data = t_iod;
@@ -2951,8 +2951,9 @@
Tcl_Eval(interpreter, "rename " MGED_DB_NAME " \"\"; rename .inmem \"\"");
/* close the geometry instance */
- if (GEDP->ged_io_data)
- BU_PUT(GEDP->ged_io_data, struct tclcad_io_data);
+ if (GEDP->ged_io_data) {
+ tclcad_destroy_io_data((struct tclcad_io_data *)GEDP->ged_io_data);
+ }
ged_close(GEDP);
BU_PUT(GEDP, struct ged);
@@ -2968,8 +2969,7 @@
GEDP->ged_delete_io_handler = &tclcad_delete_io_handler;
GEDP->ged_interp = (void *)interpreter;
GEDP->ged_interp_eval = &mged_db_search_callback;
- struct tclcad_io_data *t_iod;
- BU_GET(t_iod, struct tclcad_io_data);
+ struct tclcad_io_data *t_iod = tclcad_create_io_data();
t_iod->io_mode = TCL_READABLE;
t_iod->interp = interpreter;
GEDP->ged_io_data = t_iod;
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