Skip to content

Commit 23c3984

Browse files
committed
Stores comms created by create_comm in a map
1 parent db7770f commit 23c3984

2 files changed

Lines changed: 62 additions & 14 deletions

File tree

src/xcomm.cpp

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/xcomm.hpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ namespace xpyt
2121
{
2222
public:
2323

24+
using close_callback_type = std::function<void(std::string)>;
2425
using python_callback_type = std::function<void(py::object)>;
2526
using cpp_callback_type = std::function<void(const xeus::xmessage&)>;
2627
using buffers_sequence = xeus::buffer_sequence;
2728

2829
xcomm(const py::object& target_name, const py::object& data, const py::object& metadata, const py::object& buffers, const py::kwargs& kwargs);
2930
xcomm(xeus::xcomm&& comm);
30-
xcomm(xcomm&& comm) = default;
31-
virtual ~xcomm();
31+
xcomm(xcomm&& comm) = delete;
32+
xcomm& operator=(xcomm&& rhs) = delete;
33+
xcomm(const xcomm&) = delete;
34+
xcomm& operator=(xcomm& rhs) = delete;
35+
~xcomm() = default;
3236

3337
std::string comm_id() const;
3438
bool kernel() const;
@@ -38,6 +42,8 @@ namespace xpyt
3842
void on_msg(const python_callback_type& callback);
3943
void on_close(const python_callback_type& callback);
4044

45+
void on_close_cleanup(close_callback_type callback);
46+
4147
private:
4248

4349
// Warning: this function creates and register the target with a dummy
@@ -46,15 +52,24 @@ namespace xpyt
4652
const xeus::xtarget* target(const py::object& target_name) const;
4753
xeus::xguid id(const py::kwargs& kwargs) const;
4854
cpp_callback_type cpp_callback(const python_callback_type& callback) const;
55+
cpp_callback_type cpp_close_callback(const python_callback_type& callback) const;
4956

5057
xeus::xcomm m_comm;
58+
close_callback_type m_close_callback;
5159
};
5260

53-
struct xcomm_manager
61+
class xcomm_manager
5462
{
63+
public:
64+
5565
xcomm_manager() = default;
5666

5767
void register_target(const py::str& target_name, const py::object& callback);
68+
void register_comm(py::object comm);
69+
70+
private:
71+
72+
std::map<std::string, py::object> m_comms;
5873
};
5974

6075
py::module get_comm_module();

0 commit comments

Comments
 (0)