99// 3. _ensure_fd_no_transport
1010// 4. _ensure_resolve
1111
12+ #include < errno.h>
1213#include < iostream>
1314#include < boost/asio.hpp>
1415#include < boost/bind.hpp>
@@ -27,8 +28,14 @@ bool _hasattr(object o, const char* name)
2728 return PyObject_HasAttrString (o.ptr (), name);
2829}
2930
31+ void raise_dup_error ()
32+ {
33+ PyErr_SetString (PyExc_OSError, std::system_category ().message (errno).c_str ());
34+ throw_error_already_set ();
3035}
3136
37+ } // namespace
38+
3239void event_loop::_sock_connect_cb (object pymod_socket, object fut, object sock, object addr)
3340{
3441 try
@@ -100,30 +107,28 @@ void event_loop::call_later(double delay, object f)
100107{
101108 auto p_timer = std::make_shared<boost::asio::steady_timer>(
102109 _strand.context (),
103- std::chrono::nanoseconds ( int64_t (delay * 1e9 )));
110+ std::chrono::duration_cast<std::chrono:: nanoseconds>(std::chrono::duration< double > (delay)));
104111 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 ();}));
106113}
107114
108115void event_loop::call_at (double when, object f)
109116{
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 ();}));
121124}
122125
123126object event_loop::sock_recv (object sock, size_t nbytes)
124127{
125128 int fd = extract<int >(sock.attr (" fileno" )());
126129 int fd_dup = dup (fd);
130+ if (fd_dup == -1 )
131+ raise_dup_error ();
127132 object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
128133 _async_wait_fd (fd_dup,
129134 [py_fut, nbytes, fd=fd_dup] {
@@ -139,6 +144,8 @@ object event_loop::sock_recv_into(object sock, object buffer)
139144{
140145 int fd = extract<int >(sock.attr (" fileno" )());
141146 int fd_dup = dup (fd);
147+ if (fd_dup == -1 )
148+ raise_dup_error ();
142149 ssize_t nbytes = len (buffer);
143150 object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
144151 _async_wait_fd (fd_dup,
@@ -155,6 +162,8 @@ object event_loop::sock_sendall(object sock, object data)
155162{
156163 int fd = extract<int >(sock.attr (" fileno" )());
157164 int fd_dup = dup (fd);
165+ if (fd_dup == -1 )
166+ raise_dup_error ();
158167 char const * py_str = extract<char const *>(data.attr (" decode" )());
159168 ssize_t py_str_len = len (data);
160169 object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
@@ -187,7 +196,10 @@ object event_loop::sock_connect(object sock, object address)
187196 || PyErr_ExceptionMatches (PyExc_InterruptedError))
188197 {
189198 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));
191203 }
192204 else if (PyErr_ExceptionMatches (PyExc_SystemExit)
193205 || PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
0 commit comments