Skip to content

Commit 587c1ea

Browse files
committed
change std::future to python concurrent.futures.Future
1 parent d23977f commit 587c1ea

File tree

2 files changed

+58
-67
lines changed

2 files changed

+58
-67
lines changed

include/boost/python/eventloop.hpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,17 @@ class event_loop
8080

8181
object sock_recv(object sock, size_t nbytes);
8282

83-
size_t sock_recv_into(object sock, object buffer);
83+
object sock_recv_into(object sock, object buffer);
8484

8585
object sock_sendall(object sock, object data);
8686

87-
void sock_connect(object sock, object address);
87+
object sock_connect(object sock, object address);
8888

8989
object sock_accept(object sock);
9090

91-
void sock_sendfile(object sock, object file, int offset = 0, int count = 0, bool fallback = true);
91+
object sock_sendfile(object sock, object file, int offset = 0, int count = 0, bool fallback = true);
9292

93-
void start_tls(object transport, object protocol, object sslcontext,
93+
object start_tls(object transport, object protocol, object sslcontext,
9494
bool server_side = false,
9595
object server_hostname = object(),
9696
object ssl_handshake_timeout = object());
@@ -123,6 +123,7 @@ class event_loop
123123
object _pymod_socket = import("socket");
124124
object _pymod_traceback = import("traceback");
125125
object _pymod_logger = import("asyncio.log").attr("logger");
126+
object _pymod_concurrent_future = import("concurrent").attr("futures");
126127
object _exception_handler = object();
127128
boost::asio::io_context::strand _strand;
128129
std::unordered_map<int, std::unique_ptr<boost::asio::steady_timer>> _id_to_timer_map;

src/eventloop.cpp

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

30-
void _sock_recv_handler(
31-
std::promise<std::vector<char>>& prom_data,
32-
std::promise<size_t>& prom_nbytes_read,
33-
size_t nbytes,
34-
int fd)
30+
void _sock_recv_handler(object fut, size_t nbytes, int fd)
3531
{
3632
std::vector<char> buffer(nbytes);
37-
prom_nbytes_read.set_value(read(fd, buffer.data(), nbytes));
38-
prom_data.set_value(std::move(buffer));
33+
read(fd, buffer.data(), nbytes);
34+
fut.attr("set_result")(object(handle<>(PyBytes_FromStringAndSize(buffer.data(), nbytes))));
3935
}
4036

41-
void _sock_send_handler(std::promise<size_t>& prom, int fd, const char *py_str, ssize_t len)
37+
void _sock_recv_into_handler(object fut, size_t nbytes, int fd)
4238
{
43-
size_t nwrite = write(fd, py_str, len);
44-
prom.set_value(nwrite);
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());
4548
}
4649

47-
void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future<void>& fut, object sock, object addr)
50+
void _sock_connect_cb(object pymod_socket, object fut, object sock, object addr)
4851
{
4952
try
5053
{
@@ -55,7 +58,7 @@ void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future
5558
PyErr_SetString(PyExc_OSError, "Connect call failed {address}");
5659
throw_error_already_set();
5760
}
58-
prom.set_value();
61+
fut.attr("set_result")(object());
5962
}
6063
catch (const error_already_set& e)
6164
{
@@ -73,12 +76,12 @@ void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future
7376
else
7477
{
7578
PyErr_Clear();
76-
prom.set_exception(std::current_exception());
79+
fut.attr("set_exception")(std::current_exception());
7780
}
7881
}
7982
}
8083

81-
void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<object>& fut, object sock)
84+
void _sock_accept(event_loop& loop, object fut, object sock)
8285
{
8386
int fd = extract<int>(sock.attr("fileno")());
8487
object conn;
@@ -89,7 +92,7 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
8992
conn = ret[0];
9093
address = ret[1];
9194
conn.attr("setblocking")(object(false));
92-
prom.set_value(make_tuple(conn, address));
95+
fut.attr("set_result")(make_tuple(conn, address));
9396
}
9497
catch (const error_already_set& e)
9598
{
@@ -98,7 +101,7 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
98101
{
99102
PyErr_Clear();
100103
loop.add_reader(fd, make_function(bind(
101-
_sock_accept, boost::ref(loop), boost::ref(prom), boost::ref(fut), sock),
104+
_sock_accept, boost::ref(loop), fut, sock),
102105
default_call_policies(), boost::mpl::vector<void, object>()));
103106
}
104107
else if (PyErr_ExceptionMatches(PyExc_SystemExit)
@@ -109,22 +112,22 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
109112
else
110113
{
111114
PyErr_Clear();
112-
prom.set_exception(std::current_exception());
115+
fut.attr("set_exception")(std::current_exception());
113116
}
114117
}
115118
}
116119

117-
void _getaddrinfo_handler(object pymod_socket, std::promise<object>& prom,
120+
void _getaddrinfo_handler(object pymod_socket, object fut,
118121
object host, int port, int family, int type, int proto, int flags)
119122
{
120123
object res = pymod_socket.attr("getaddrinfo")(host, port, family, type, proto, flags);
121-
prom.set_value(res);
124+
fut.attr("set_result")(res);
122125
}
123126

124-
void _getnameinfo_handler(object pymod_socket, std::promise<object>& prom, object sockaddr, int flags)
127+
void _getnameinfo_handler(object pymod_socket, object fut, object sockaddr, int flags)
125128
{
126129
object res = pymod_socket.attr("getnameinfo")(sockaddr, flags);
127-
prom.set_value(res);
130+
fut.attr("set_result")(res);
128131
}
129132

130133
}
@@ -193,58 +196,46 @@ void event_loop::call_at(double when, object f)
193196
object event_loop::sock_recv(object sock, size_t nbytes)
194197
{
195198
int fd = extract<int>(sock.attr("fileno")());
196-
std::promise<std::vector<char>> prom_data;
197-
std::future<std::vector<char>> fut_data = prom_data.get_future();
198-
std::promise<size_t> prom_nbytes_read;
199-
std::future<size_t> fut_nbytes_read = prom_nbytes_read.get_future();
200-
add_reader(fd, make_function(bind(_sock_recv_handler,
201-
boost::ref(prom_data), boost::ref(prom_nbytes_read), nbytes, fd),
199+
object fut = _pymod_concurrent_future.attr("Future")();
200+
add_reader(fd, make_function(bind(_sock_recv_handler, fut, nbytes, fd),
202201
default_call_policies(), boost::mpl::vector<void, object>()));
203-
return object(handle<>(PyBytes_FromStringAndSize(fut_data.get().data(), nbytes)));
202+
return fut;
204203
}
205204

206-
size_t event_loop::sock_recv_into(object sock, object buffer)
205+
object event_loop::sock_recv_into(object sock, object buffer)
207206
{
208207
int fd = extract<int>(sock.attr("fileno")());
209208
ssize_t nbytes = len(buffer);
210-
std::promise<std::vector<char>> prom_data;
211-
std::future<std::vector<char>> fut_data = prom_data.get_future();
212-
std::promise<size_t> prom_nbytes_read;
213-
std::future<size_t> fut_nbytes_read = prom_nbytes_read.get_future();
214-
add_reader(fd, make_function(bind(_sock_recv_handler,
215-
boost::ref(prom_data), boost::ref(prom_nbytes_read), nbytes, fd),
209+
object fut = _pymod_concurrent_future.attr("Future")();
210+
add_reader(fd, make_function(bind(_sock_recv_into_handler, fut, nbytes, fd),
216211
default_call_policies(), boost::mpl::vector<void, object>()));
217-
buffer = object(handle<>(PyBytes_FromStringAndSize(fut_data.get().data(), nbytes)));
218-
return fut_nbytes_read.get();
212+
return fut;
219213
}
220214

221215
object event_loop::sock_sendall(object sock, object data)
222216
{
223217
int fd = extract<int>(sock.attr("fileno")());
224218
char const* py_str = extract<char const*>(data.attr("decode")());
225219
ssize_t py_str_len = len(data);
226-
std::promise<size_t> prom;
227-
std::future<size_t> fut = prom.get_future();
228-
add_writer(fd, make_function(bind(_sock_send_handler, std::ref(prom), fd, py_str, py_str_len),
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),
229222
default_call_policies(), boost::mpl::vector<void, object>()));
230-
fut.wait();
231-
return object();
223+
return fut;
232224
}
233225

234-
void event_loop::sock_connect(object sock, object address)
226+
object event_loop::sock_connect(object sock, object address)
235227
{
236228

237229
if (!_hasattr(_pymod_socket, "AF_UNIX") || sock.attr("family") != _pymod_socket.attr("AF_UNIX"))
238230
{
239231
// TODO: _ensure_resolve
240232
}
241-
std::promise<void> prom;
242-
std::future<void> fut = prom.get_future();
233+
object fut = _pymod_concurrent_future.attr("Future")();
243234
int fd = extract<int>(sock.attr("fileno")());
244235
try
245236
{
246237
sock.attr("connect")(address);
247-
prom.set_value();
238+
fut.attr("set_result")(object());
248239
}
249240
catch (const error_already_set& e)
250241
{
@@ -253,7 +244,7 @@ void event_loop::sock_connect(object sock, object address)
253244
{
254245
PyErr_Clear();
255246
add_writer(fd, make_function(bind(
256-
_sock_connect_cb, _pymod_socket, boost::ref(prom), boost::ref(fut), sock, address),
247+
_sock_connect_cb, _pymod_socket, fut, sock, address),
257248
default_call_policies(), boost::mpl::vector<void, object>()));
258249
}
259250
else if (PyErr_ExceptionMatches(PyExc_SystemExit)
@@ -264,55 +255,54 @@ void event_loop::sock_connect(object sock, object address)
264255
else
265256
{
266257
PyErr_Clear();
267-
prom.set_exception(std::current_exception());
258+
fut.attr("set_exception")(std::current_exception());
268259
}
269260
}
270-
fut.wait();
261+
return fut;
271262
}
272263

273264
object event_loop::sock_accept(object sock)
274265
{
275-
std::promise<object> prom;
276-
std::future<object> fut = prom.get_future();
277-
_sock_accept(*this, prom, fut, sock);
278-
return fut.get();
266+
object fut = _pymod_concurrent_future.attr("Future")();
267+
_sock_accept(*this, fut, sock);
268+
return fut;
279269
}
280270

281271
// TODO: implement this
282-
void event_loop::sock_sendfile(object sock, object file, int offset, int count, bool fallback)
272+
object event_loop::sock_sendfile(object sock, object file, int offset, int count, bool fallback)
283273
{
284274
PyErr_SetString(PyExc_NotImplementedError, "Not implemented!");
285275
throw_error_already_set();
276+
return object();
286277
}
287278

288279
// TODO: implement this
289-
void event_loop::start_tls(object transport, object protocol, object sslcontext,
280+
object event_loop::start_tls(object transport, object protocol, object sslcontext,
290281
bool server_side, object server_hostname, object ssl_handshake_timeout)
291282
{
292283
PyErr_SetString(PyExc_NotImplementedError, "Not implemented!");
293284
throw_error_already_set();
285+
return object();
294286
}
295287

296288
object event_loop::getaddrinfo(object host, int port, int family, int type, int proto, int flags)
297289
{
298-
std::promise<object> prom;
299-
std::future<object> fut = prom.get_future();
290+
object fut = _pymod_concurrent_future.attr("Future")();
300291
call_soon(make_function(
301-
bind(_getaddrinfo_handler, _pymod_socket, boost::ref(prom), host, port, family, type, proto, flags),
292+
bind(_getaddrinfo_handler, _pymod_socket, fut, host, port, family, type, proto, flags),
302293
default_call_policies(),
303294
boost::mpl::vector<void, object>()));
304-
return fut.get();
295+
return fut;
305296
}
306297

307298
object event_loop::getnameinfo(object sockaddr, int flags)
308299
{
309-
std::promise<object> prom;
310-
std::future<object> fut = prom.get_future();
300+
object fut = _pymod_concurrent_future.attr("Future")();
311301
call_soon(make_function(
312-
bind(_getnameinfo_handler, _pymod_socket, boost::ref(prom), sockaddr, flags),
302+
bind(_getnameinfo_handler, _pymod_socket, fut, sockaddr, flags),
313303
default_call_policies(),
314304
boost::mpl::vector<void, object>()));
315-
return fut.get();
305+
return fut;
316306
}
317307

318308
void event_loop::default_exception_handler(object context)

0 commit comments

Comments
 (0)