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,28 @@ 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
+ auto p_timer = std::make_shared<boost::asio::steady_timer>(
118
+ _strand.context (),
119
+ std::chrono::steady_clock::time_point (
120
+ std::chrono::duration_cast<std::chrono::nanoseconds>(
121
+ std::chrono::duration<double >(when))));
122
+ p_timer->async_wait (boost::asio::bind_executor (_strand,
123
+ [f, p_timer] (const boost::system ::error_code& ec) {f ();}));
121
124
}
122
125
123
126
object event_loop::sock_recv (object sock, size_t nbytes)
124
127
{
125
128
int fd = extract<int >(sock.attr (" fileno" )());
126
129
int fd_dup = dup (fd);
130
+ if (fd_dup == -1 )
131
+ raise_dup_error ();
127
132
object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
128
133
_async_wait_fd (fd_dup,
129
134
[py_fut, nbytes, fd=fd_dup] {
@@ -139,6 +144,8 @@ object event_loop::sock_recv_into(object sock, object buffer)
139
144
{
140
145
int fd = extract<int >(sock.attr (" fileno" )());
141
146
int fd_dup = dup (fd);
147
+ if (fd_dup == -1 )
148
+ raise_dup_error ();
142
149
ssize_t nbytes = len (buffer);
143
150
object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
144
151
_async_wait_fd (fd_dup,
@@ -155,6 +162,8 @@ object event_loop::sock_sendall(object sock, object data)
155
162
{
156
163
int fd = extract<int >(sock.attr (" fileno" )());
157
164
int fd_dup = dup (fd);
165
+ if (fd_dup == -1 )
166
+ raise_dup_error ();
158
167
char const * py_str = extract<char const *>(data.attr (" decode" )());
159
168
ssize_t py_str_len = len (data);
160
169
object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
@@ -187,7 +196,10 @@ object event_loop::sock_connect(object sock, object address)
187
196
|| PyErr_ExceptionMatches (PyExc_InterruptedError))
188
197
{
189
198
PyErr_Clear ();
190
- _async_wait_fd (dup (fd), bind (_sock_connect_cb, _pymod_socket, py_fut, sock, address), _write_key (fd));
199
+ int fd_dup = dup (fd);
200
+ if (fd_dup == -1 )
201
+ raise_dup_error ();
202
+ _async_wait_fd (fd_dup, bind (_sock_connect_cb, _pymod_socket, py_fut, sock, address), _write_key (fd));
191
203
}
192
204
else if (PyErr_ExceptionMatches (PyExc_SystemExit)
193
205
|| PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
0 commit comments