@@ -27,26 +27,6 @@ bool _hasattr(object o, const char* name)
27
27
return PyObject_HasAttrString (o.ptr (), name);
28
28
}
29
29
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
-
50
30
void _sock_connect_cb (object pymod_socket, object fut, object sock, object addr)
51
31
{
52
32
try
@@ -117,19 +97,6 @@ void _sock_accept(event_loop& loop, object fut, object sock)
117
97
}
118
98
}
119
99
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
-
133
100
}
134
101
135
102
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)
169
136
170
137
void event_loop::call_later (double delay, object f)
171
138
{
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 ();}));
186
144
}
187
145
188
146
void event_loop::call_at (double when, object f)
@@ -196,31 +154,48 @@ void event_loop::call_at(double when, object f)
196
154
object event_loop::sock_recv (object sock, size_t nbytes)
197
155
{
198
156
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
+ },
201
165
default_call_policies (), boost::mpl::vector<void , object>()));
202
- return fut ;
166
+ return py_fut ;
203
167
}
204
168
205
169
object event_loop::sock_recv_into (object sock, object buffer)
206
170
{
207
171
int fd = extract<int >(sock.attr (" fileno" )());
172
+ int fd_dup = dup (fd);
208
173
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
+ },
211
181
default_call_policies (), boost::mpl::vector<void , object>()));
212
- return fut ;
182
+ return py_fut ;
213
183
}
214
184
215
185
object event_loop::sock_sendall (object sock, object data)
216
186
{
217
187
int fd = extract<int >(sock.attr (" fileno" )());
188
+ int fd_dup = dup (fd);
218
189
char const * py_str = extract<char const *>(data.attr (" decode" )());
219
190
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
+ },
222
197
default_call_policies (), boost::mpl::vector<void , object>()));
223
- return fut ;
198
+ return py_fut ;
224
199
}
225
200
226
201
object event_loop::sock_connect (object sock, object address)
@@ -243,7 +218,7 @@ object event_loop::sock_connect(object sock, object address)
243
218
|| PyErr_ExceptionMatches (PyExc_InterruptedError))
244
219
{
245
220
PyErr_Clear ();
246
- add_writer (fd , make_function (bind (
221
+ add_writer (dup (fd) , make_function (bind (
247
222
_sock_connect_cb, _pymod_socket, fut, sock, address),
248
223
default_call_policies (), boost::mpl::vector<void , object>()));
249
224
}
@@ -287,22 +262,28 @@ object event_loop::start_tls(object transport, object protocol, object sslcontex
287
262
288
263
object event_loop::getaddrinfo (object host, int port, int family, int type, int proto, int flags)
289
264
{
290
- object fut = _pymod_concurrent_future.attr (" Future" )();
265
+ object py_fut = _pymod_concurrent_future.attr (" Future" )();
291
266
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
+ },
293
271
default_call_policies (),
294
272
boost::mpl::vector<void , object>()));
295
- return fut ;
273
+ return py_fut ;
296
274
}
297
275
298
276
object event_loop::getnameinfo (object sockaddr, int flags)
299
277
{
300
- object fut = _pymod_concurrent_future.attr (" Future" )();
278
+ object py_fut = _pymod_concurrent_future.attr (" Future" )();
301
279
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
+ },
303
284
default_call_policies (),
304
285
boost::mpl::vector<void , object>()));
305
- return fut ;
286
+ return py_fut ;
306
287
}
307
288
308
289
void event_loop::default_exception_handler (object context)
@@ -411,9 +392,9 @@ void event_loop::call_exception_handler(object context)
411
392
PyObject *ptype, *pvalue, *ptraceback;
412
393
PyErr_Fetch (&ptype, &pvalue, &ptraceback);
413
394
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)} ;
417
398
try
418
399
{
419
400
dict tmp_dict;
0 commit comments