Skip to content

Commit 914a18d

Browse files
committed
remove _id_to_timer_map; change sock_recv_handlers to lambdas
1 parent 587c1ea commit 914a18d

File tree

2 files changed

+48
-71
lines changed

2 files changed

+48
-71
lines changed

include/boost/python/eventloop.hpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ class event_loop
3737
// TODO: An instance of asyncio.Handle is returned, which can be used later to cancel the callback.
3838
inline void call_soon(object f)
3939
{
40-
_strand.post([f, loop=this] {
41-
f(boost::ref(*loop));
42-
});
40+
_strand.post([f, loop=this] {f();});
4341
return;
4442
}
4543

@@ -118,15 +116,13 @@ class event_loop
118116
void call_exception_handler(object context);
119117

120118
private:
121-
int64_t _timer_id = 0;
122119
object _pymod_ssl = object();
123120
object _pymod_socket = import("socket");
124121
object _pymod_traceback = import("traceback");
125122
object _pymod_logger = import("asyncio.log").attr("logger");
126123
object _pymod_concurrent_future = import("concurrent").attr("futures");
127124
object _exception_handler = object();
128125
boost::asio::io_context::strand _strand;
129-
std::unordered_map<int, std::unique_ptr<boost::asio::steady_timer>> _id_to_timer_map;
130126
// read: key = fd * 2 + 0, write: key = fd * 2 + 1
131127
std::unordered_map<int, std::unique_ptr<boost::asio::posix::stream_descriptor>> _descriptor_map;
132128
std::chrono::steady_clock::time_point _created_time;

src/eventloop.cpp

+47-66
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,6 @@ bool _hasattr(object o, const char* name)
2727
return PyObject_HasAttrString(o.ptr(), name);
2828
}
2929

30-
void _sock_recv_handler(object fut, size_t nbytes, int fd)
31-
{
32-
std::vector<char> buffer(nbytes);
33-
read(fd, buffer.data(), nbytes);
34-
fut.attr("set_result")(object(handle<>(PyBytes_FromStringAndSize(buffer.data(), nbytes))));
35-
}
36-
37-
void _sock_recv_into_handler(object fut, size_t nbytes, int fd)
38-
{
39-
std::vector<char> buffer(nbytes);
40-
ssize_t nbytes_read = read(fd, buffer.data(), nbytes);
41-
fut.attr("set_result")(nbytes_read);
42-
}
43-
44-
void _sock_send_handler(object fut, int fd, const char *py_str, ssize_t len)
45-
{
46-
write(fd, py_str, len);
47-
fut.attr("set_result")(object());
48-
}
49-
5030
void _sock_connect_cb(object pymod_socket, object fut, object sock, object addr)
5131
{
5232
try
@@ -117,19 +97,6 @@ void _sock_accept(event_loop& loop, object fut, object sock)
11797
}
11898
}
11999

120-
void _getaddrinfo_handler(object pymod_socket, object fut,
121-
object host, int port, int family, int type, int proto, int flags)
122-
{
123-
object res = pymod_socket.attr("getaddrinfo")(host, port, family, type, proto, flags);
124-
fut.attr("set_result")(res);
125-
}
126-
127-
void _getnameinfo_handler(object pymod_socket, object fut, object sockaddr, int flags)
128-
{
129-
object res = pymod_socket.attr("getnameinfo")(sockaddr, flags);
130-
fut.attr("set_result")(res);
131-
}
132-
133100
}
134101

135102
void event_loop::_add_reader_or_writer(int fd, object f, int key)
@@ -169,20 +136,11 @@ void event_loop::_remove_reader_or_writer(int key)
169136

170137
void event_loop::call_later(double delay, object f)
171138
{
172-
// add timer
173-
_id_to_timer_map.emplace(_timer_id,
174-
std::move(std::make_unique<boost::asio::steady_timer>(_strand.context(),
175-
std::chrono::steady_clock::now() + std::chrono::nanoseconds(int64_t(delay * 1e9))))
176-
);
177-
178-
_id_to_timer_map.find(_timer_id)->second->async_wait(
179-
// remove timer
180-
boost::asio::bind_executor(_strand, [id=_timer_id, f, loop=this] (const boost::system::error_code& ec)
181-
{
182-
loop->_id_to_timer_map.erase(id);
183-
loop->call_soon(f);
184-
}));
185-
_timer_id++;
139+
auto p_timer = std::make_shared<boost::asio::steady_timer>(_strand.context(),
140+
std::chrono::nanoseconds(int64_t(delay * 1e9)));
141+
p_timer->async_wait(boost::asio::bind_executor(
142+
_strand,
143+
[f, p_timer, this] (const boost::system::error_code& ec) {f();}));
186144
}
187145

188146
void event_loop::call_at(double when, object f)
@@ -196,31 +154,48 @@ void event_loop::call_at(double when, object f)
196154
object event_loop::sock_recv(object sock, size_t nbytes)
197155
{
198156
int fd = extract<int>(sock.attr("fileno")());
199-
object fut = _pymod_concurrent_future.attr("Future")();
200-
add_reader(fd, make_function(bind(_sock_recv_handler, fut, nbytes, fd),
157+
int fd_dup = dup(fd);
158+
object py_fut = _pymod_concurrent_future.attr("Future")();
159+
add_reader(fd_dup, make_function(
160+
[py_fut, nbytes, fd=fd_dup] (object obj) {
161+
std::vector<char> buffer(nbytes);
162+
read(fd, buffer.data(), nbytes);
163+
py_fut.attr("set_result")(object(handle<>(PyBytes_FromStringAndSize(buffer.data(), nbytes))));
164+
},
201165
default_call_policies(), boost::mpl::vector<void, object>()));
202-
return fut;
166+
return py_fut;
203167
}
204168

205169
object event_loop::sock_recv_into(object sock, object buffer)
206170
{
207171
int fd = extract<int>(sock.attr("fileno")());
172+
int fd_dup = dup(fd);
208173
ssize_t nbytes = len(buffer);
209-
object fut = _pymod_concurrent_future.attr("Future")();
210-
add_reader(fd, make_function(bind(_sock_recv_into_handler, fut, nbytes, fd),
174+
object py_fut = _pymod_concurrent_future.attr("Future")();
175+
add_reader(fd_dup, make_function(
176+
[py_fut, nbytes, fd=fd_dup] (object obj) {
177+
std::vector<char> buffer(nbytes);
178+
ssize_t nbytes_read = read(fd, buffer.data(), nbytes);
179+
py_fut.attr("set_result")(nbytes_read);
180+
},
211181
default_call_policies(), boost::mpl::vector<void, object>()));
212-
return fut;
182+
return py_fut;
213183
}
214184

215185
object event_loop::sock_sendall(object sock, object data)
216186
{
217187
int fd = extract<int>(sock.attr("fileno")());
188+
int fd_dup = dup(fd);
218189
char const* py_str = extract<char const*>(data.attr("decode")());
219190
ssize_t py_str_len = len(data);
220-
object fut = _pymod_concurrent_future.attr("Future")();
221-
add_writer(fd, make_function(bind(_sock_send_handler, fut, fd, py_str, py_str_len),
191+
object py_fut = _pymod_concurrent_future.attr("Future")();
192+
add_writer(fd_dup, make_function(
193+
[py_fut, fd, py_str, py_str_len] (object obj) {
194+
write(fd, py_str, py_str_len);
195+
py_fut.attr("set_result")(object());
196+
},
222197
default_call_policies(), boost::mpl::vector<void, object>()));
223-
return fut;
198+
return py_fut;
224199
}
225200

226201
object event_loop::sock_connect(object sock, object address)
@@ -243,7 +218,7 @@ object event_loop::sock_connect(object sock, object address)
243218
|| PyErr_ExceptionMatches(PyExc_InterruptedError))
244219
{
245220
PyErr_Clear();
246-
add_writer(fd, make_function(bind(
221+
add_writer(dup(fd), make_function(bind(
247222
_sock_connect_cb, _pymod_socket, fut, sock, address),
248223
default_call_policies(), boost::mpl::vector<void, object>()));
249224
}
@@ -287,22 +262,28 @@ object event_loop::start_tls(object transport, object protocol, object sslcontex
287262

288263
object event_loop::getaddrinfo(object host, int port, int family, int type, int proto, int flags)
289264
{
290-
object fut = _pymod_concurrent_future.attr("Future")();
265+
object py_fut = _pymod_concurrent_future.attr("Future")();
291266
call_soon(make_function(
292-
bind(_getaddrinfo_handler, _pymod_socket, fut, host, port, family, type, proto, flags),
267+
[this, py_fut, host, port, family, type, proto, flags] (object obj) {
268+
object res = _pymod_socket.attr("getaddrinfo")(host, port, family, type, proto, flags);
269+
py_fut.attr("set_result")(res);
270+
},
293271
default_call_policies(),
294272
boost::mpl::vector<void, object>()));
295-
return fut;
273+
return py_fut;
296274
}
297275

298276
object event_loop::getnameinfo(object sockaddr, int flags)
299277
{
300-
object fut = _pymod_concurrent_future.attr("Future")();
278+
object py_fut = _pymod_concurrent_future.attr("Future")();
301279
call_soon(make_function(
302-
bind(_getnameinfo_handler, _pymod_socket, fut, sockaddr, flags),
280+
[this, py_fut, sockaddr, flags] (object obj) {
281+
object res = _pymod_socket.attr("getnameinfo")(sockaddr, flags);
282+
py_fut.attr("set_result")(res);
283+
},
303284
default_call_policies(),
304285
boost::mpl::vector<void, object>()));
305-
return fut;
286+
return py_fut;
306287
}
307288

308289
void event_loop::default_exception_handler(object context)
@@ -411,9 +392,9 @@ void event_loop::call_exception_handler(object context)
411392
PyObject *ptype, *pvalue, *ptraceback;
412393
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
413394
PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
414-
object type(handle<>(ptype));
415-
object value(handle<>(pvalue));
416-
object traceback(handle<>(ptraceback));
395+
object type{handle<>(ptype)};
396+
object value{handle<>(pvalue)};
397+
object traceback{handle<>(ptraceback)};
417398
try
418399
{
419400
dict tmp_dict;

0 commit comments

Comments
 (0)