9
9
// 3. _ensure_fd_no_transport
10
10
// 4. _ensure_resolve
11
11
12
+ #include < errno.h>
12
13
#include < iostream>
13
14
#include < boost/asio.hpp>
14
15
#include < boost/bind.hpp>
@@ -27,8 +28,14 @@ bool _hasattr(object o, const char* name)
27
28
return PyObject_HasAttrString (o.ptr (), name);
28
29
}
29
30
31
+ void raise_dup_error ()
32
+ {
33
+ PyErr_SetString (PyExc_OSError, std::system_category ().message (errno).c_str ());
34
+ throw_error_already_set ();
30
35
}
31
36
37
+ } // namespace
38
+
32
39
void event_loop::_sock_connect_cb (object pymod_socket, object fut, object sock, object addr)
33
40
{
34
41
try
@@ -100,30 +107,27 @@ void event_loop::call_later(double delay, object f)
100
107
{
101
108
auto p_timer = std::make_shared<boost::asio::steady_timer>(
102
109
_strand.context (),
103
- std::chrono::nanoseconds ( int64_t (delay * 1e9 )));
110
+ std::chrono::duration_cast<std::chrono:: nanoseconds>(std::chrono::duration< double > (delay)));
104
111
p_timer->async_wait (boost::asio::bind_executor (_strand,
105
- [f, p_timer, this ] (const boost::system ::error_code& ec) {f ();}));
112
+ [f, p_timer] (const boost::system ::error_code& ec) {f ();}));
106
113
}
107
114
108
115
void event_loop::call_at (double when, object f)
109
116
{
110
- double diff = when - time ();
111
- if (diff > 0 )
112
- {
113
- auto p_timer = std::make_shared<boost::asio::steady_timer>(
114
- _strand.context (),
115
- std::chrono::nanoseconds (int64_t (diff * 1e9 )));
116
- p_timer->async_wait (boost::asio::bind_executor (_strand,
117
- [f, p_timer, this ] (const boost::system ::error_code& ec) {f ();}));
118
- return ;
119
- }
120
- call_soon (f);
117
+ using sc = std::chrono::steady_clock;
118
+ auto p_timer = std::make_shared<boost::asio::steady_timer>(
119
+ _strand.context (),
120
+ sc::duration (static_cast <sc::time_point::rep>(when)));
121
+ p_timer->async_wait (boost::asio::bind_executor (_strand,
122
+ [f, p_timer] (const boost::system ::error_code& ec) {f ();}));
121
123
}
122
124
123
125
object event_loop::sock_recv (object sock, size_t nbytes)
124
126
{
125
127
int fd = extract<int >(sock.attr (" fileno" )());
126
128
int fd_dup = dup (fd);
129
+ if (fd_dup == -1 )
130
+ raise_dup_error ();
127
131
object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
128
132
_async_wait_fd (fd_dup,
129
133
[py_fut, nbytes, fd=fd_dup] {
@@ -139,6 +143,8 @@ object event_loop::sock_recv_into(object sock, object buffer)
139
143
{
140
144
int fd = extract<int >(sock.attr (" fileno" )());
141
145
int fd_dup = dup (fd);
146
+ if (fd_dup == -1 )
147
+ raise_dup_error ();
142
148
ssize_t nbytes = len (buffer);
143
149
object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
144
150
_async_wait_fd (fd_dup,
@@ -155,6 +161,8 @@ object event_loop::sock_sendall(object sock, object data)
155
161
{
156
162
int fd = extract<int >(sock.attr (" fileno" )());
157
163
int fd_dup = dup (fd);
164
+ if (fd_dup == -1 )
165
+ raise_dup_error ();
158
166
char const * py_str = extract<char const *>(data.attr (" decode" )());
159
167
ssize_t py_str_len = len (data);
160
168
object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
@@ -187,7 +195,10 @@ object event_loop::sock_connect(object sock, object address)
187
195
|| PyErr_ExceptionMatches (PyExc_InterruptedError))
188
196
{
189
197
PyErr_Clear ();
190
- _async_wait_fd (dup (fd), bind (_sock_connect_cb, _pymod_socket, py_fut, sock, address), _write_key (fd));
198
+ int fd_dup = dup (fd);
199
+ if (fd_dup == -1 )
200
+ raise_dup_error ();
201
+ _async_wait_fd (fd_dup, bind (_sock_connect_cb, _pymod_socket, py_fut, sock, address), _write_key (fd));
191
202
}
192
203
else if (PyErr_ExceptionMatches (PyExc_SystemExit)
193
204
|| PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
@@ -388,4 +399,4 @@ void event_loop::call_exception_handler(object context)
388
399
}
389
400
390
401
391
- }}}
402
+ }}} // namespace boost::python
0 commit comments