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,27 @@ 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+ 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 ();}));
121123}
122124
123125object event_loop::sock_recv (object sock, size_t nbytes)
124126{
125127 int fd = extract<int >(sock.attr (" fileno" )());
126128 int fd_dup = dup (fd);
129+ if (fd_dup == -1 )
130+ raise_dup_error ();
127131 object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
128132 _async_wait_fd (fd_dup,
129133 [py_fut, nbytes, fd=fd_dup] {
@@ -139,6 +143,8 @@ object event_loop::sock_recv_into(object sock, object buffer)
139143{
140144 int fd = extract<int >(sock.attr (" fileno" )());
141145 int fd_dup = dup (fd);
146+ if (fd_dup == -1 )
147+ raise_dup_error ();
142148 ssize_t nbytes = len (buffer);
143149 object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
144150 _async_wait_fd (fd_dup,
@@ -155,6 +161,8 @@ object event_loop::sock_sendall(object sock, object data)
155161{
156162 int fd = extract<int >(sock.attr (" fileno" )());
157163 int fd_dup = dup (fd);
164+ if (fd_dup == -1 )
165+ raise_dup_error ();
158166 char const * py_str = extract<char const *>(data.attr (" decode" )());
159167 ssize_t py_str_len = len (data);
160168 object py_fut = _py_wrap_future (_pymod_concurrent_future.attr (" Future" )());
@@ -187,7 +195,10 @@ object event_loop::sock_connect(object sock, object address)
187195 || PyErr_ExceptionMatches (PyExc_InterruptedError))
188196 {
189197 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));
191202 }
192203 else if (PyErr_ExceptionMatches (PyExc_SystemExit)
193204 || PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
@@ -388,4 +399,4 @@ void event_loop::call_exception_handler(object context)
388399}
389400
390401
391- }}}
402+ }}} // namespace boost::python
0 commit comments