@@ -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-
5030void _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
135102void 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
170137void 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
188146void event_loop::call_at (double when, object f)
@@ -196,31 +154,48 @@ void event_loop::call_at(double when, object f)
196154object 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
205169object 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
215185object 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
226201object 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
288263object 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
298276object 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
308289void 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