@@ -48,10 +48,6 @@ namespace xpyt
4848 {
4949 }
5050
51- xcomm::~xcomm ()
52- {
53- }
54-
5551 std::string xcomm::comm_id () const
5652 {
5753 return m_comm.id ();
@@ -79,7 +75,16 @@ namespace xpyt
7975
8076 void xcomm::on_close (const python_callback_type& callback)
8177 {
82- m_comm.on_close (cpp_callback (callback));
78+ m_comm.on_close (cpp_close_callback (callback));
79+ }
80+
81+ void xcomm::on_close_cleanup (close_callback_type callback)
82+ {
83+ m_close_callback = std::move (callback);
84+ m_comm.on_close ([this ](const xeus::xmessage&)
85+ {
86+ m_close_callback (comm_id ());
87+ });
8388 }
8489
8590 const xeus::xtarget* xcomm::target (const py::object& target_name) const
@@ -116,6 +121,18 @@ namespace xpyt
116121 };
117122 }
118123
124+ auto xcomm::cpp_close_callback (const python_callback_type& py_callback) const -> cpp_callback_type
125+ {
126+ return [this , py_callback](const xeus::xmessage& msg)
127+ {
128+ XPYT_HOLDING_GIL (py_callback (cppmessage_to_pymessage (msg)))
129+ if (m_close_callback)
130+ {
131+ m_close_callback (comm_id ());
132+ }
133+ };
134+ }
135+
119136 void xcomm_manager::register_target (const py::str& target_name, const py::object& callback)
120137 {
121138 auto target_callback = [callback] (xeus::xcomm&& comm, const xeus::xmessage& msg)
@@ -128,6 +145,20 @@ namespace xpyt
128145 );
129146 }
130147
148+ void xcomm_manager::register_comm (py::object pycomm)
149+ {
150+ // pycomm was created with initial refcount = 0
151+ // Therefore we need to increment it to avoid its
152+ // deletion by the garbage collector
153+ pycomm.inc_ref ();
154+ xcomm& comm = pycomm.cast <xcomm&>();
155+ comm.on_close_cleanup ([this ](std::string id)
156+ {
157+ XPYT_HOLDING_GIL (m_comms.erase (id))
158+ });
159+ m_comms[comm.comm_id ()] = pycomm;
160+ }
161+
131162 /* **************
132163 * comm module *
133164 ***************/
@@ -150,18 +181,20 @@ namespace xpyt
150181
151182 py::class_<xcomm_manager>(comm_module, " CommManager" )
152183 .def (py::init<>())
153- .def (" register_target" , &xcomm_manager::register_target);
154-
155- comm_module.def (" create_comm" , [&comm_module](py::args objs, py::kwargs kw) {
156- return comm_module.attr (" Comm" )(*objs, **kw);
157- });
184+ .def (" register_target" , &xcomm_manager::register_target)
185+ .def (" register_comm" , &xcomm_manager::register_comm);
158186
159187 comm_module.def (" get_comm_manager" , [&comm_module]() {
160188 static py::object comm_manager = comm_module.attr (" CommManager" )();
161-
162189 return comm_manager;
163190 });
164191
192+ comm_module.def (" create_comm" , [&comm_module](py::args objs, py::kwargs kw) {
193+ py::object comm = comm_module.attr (" Comm" )(*objs, **kw);
194+ comm_module.attr (" get_comm_manager" )().attr (" register_comm" )(comm);
195+ return comm;
196+ });
197+
165198 return comm_module;
166199 }
167200
0 commit comments