99//  3. _ensure_fd_no_transport
1010//  4. _ensure_resolve
1111
12+ #include  < iostream> 
1213#include  < boost/asio.hpp> 
1314#include  < boost/bind.hpp> 
1415#include  < boost/python.hpp> 
@@ -53,6 +54,7 @@ void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future
5354            //  TODO: print the address
5455            PyErr_SetString (PyExc_OSError, " Connect call failed {address}"  );
5556        }
57+         prom.set_value ();
5658    }
5759    catch  (const  error_already_set& e)
5860    {
@@ -67,15 +69,10 @@ void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future
6769        {
6870            //  raise
6971        }
70-         else  if  (PyErr_ExceptionMatches (PyExc_BaseException))
71-         {
72-             PyErr_Clear ();
73-             prom.set_exception (std::current_exception ());
74-         }
7572        else 
7673        {
7774            PyErr_Clear ();
78-             prom.set_value ( );
75+             prom.set_exception ( std::current_exception () );
7976        }
8077    }
8178}
@@ -91,6 +88,7 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
9188        conn = ret[0 ];
9289        address = ret[1 ];
9390        conn.attr (" setblocking"  )(object (false ));
91+         prom.set_value (make_tuple (conn, address));
9492    }
9593    catch  (const  error_already_set& e)
9694    {
@@ -107,19 +105,27 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
107105        {
108106            //  raise
109107        }
110-         else  if  (PyErr_ExceptionMatches (PyExc_BaseException))
111-         {
112-             PyErr_Clear ();
113-             prom.set_exception (std::current_exception ());
114-         }
115108        else 
116109        {
117110            PyErr_Clear ();
118-             prom.set_value ( make_tuple (conn, address ));
111+             prom.set_exception ( std::current_exception ( ));
119112        }
120113    }  
121114}
122115
116+ void  _getaddrinfo_handler (object pymod_socket, std::promise<object>& prom, 
117+     object host, int  port, int  family, int  type, int  proto, int  flags)
118+ {
119+     object res = pymod_socket.attr (" getaddrinfo"  )(host, port, family, type, proto, flags);
120+     prom.set_value (res);
121+ }
122+ 
123+ void  _getnameinfo_handler (object pymod_socket, std::promise<object>& prom, object sockaddr, int  flags)
124+ {
125+     object res = pymod_socket.attr (" getnameinfo"  )(sockaddr, flags);
126+     prom.set_value (res);
127+ }
128+ 
123129}
124130
125131void  event_loop::_add_reader_or_writer (int  fd, object f, int  key)
@@ -237,6 +243,7 @@ void event_loop::sock_connect(object sock, object address)
237243    try  
238244    {
239245        sock.attr (" connect"  )(address);
246+         prom.set_value ();
240247    }
241248    catch  (const  error_already_set& e)
242249    {
@@ -253,15 +260,10 @@ void event_loop::sock_connect(object sock, object address)
253260        {
254261            //  raise
255262        }
256-         else  if  (PyErr_ExceptionMatches (PyExc_BaseException))
257-         {
258-             PyErr_Clear ();
259-             prom.set_exception (std::current_exception ());
260-         }
261263        else 
262264        {
263265            PyErr_Clear ();
264-             prom.set_value ( );
266+             prom.set_exception ( std::current_exception () );
265267        }
266268    }
267269    fut.wait ();
@@ -281,4 +283,164 @@ void event_loop::sock_sendfile(object sock, object file, int offset, int count,
281283    PyErr_SetString (PyExc_NotImplementedError, " Not implemented!"  );
282284}
283285
286+ //  TODO: implement this
287+ void  event_loop::start_tls (object transport, object protocol, object sslcontext, 
288+     bool  server_side, object server_hostname, object ssl_handshake_timeout)
289+ {
290+     PyErr_SetString (PyExc_NotImplementedError, " Not implemented!"  );
291+ }
292+ 
293+ object event_loop::getaddrinfo (object host, int  port, int  family, int  type, int  proto, int  flags)
294+ {
295+     call_soon (make_function (bind (_getaddrinfo_handler, host, port, family, type, proto, flags),
296+         default_call_policies (), boost::mpl::vector<void , object>()));
297+     return  object ();
298+ }
299+ 
300+ object event_loop::getnameinfo (object sockaddr, int  flags)
301+ {
302+     call_soon (make_function (bind (_getnameinfo_handler, sockaddr, flags),
303+         default_call_policies (), boost::mpl::vector<void , object>()));
304+     return  object ();
305+ }
306+ 
307+ void  event_loop::default_exception_handler (object context)
308+ {
309+     object message = context.attr (" get"  )(str (" message"  ));
310+     if  (message == object ())
311+     {
312+         message = str (" Unhandled exception in event loop"  );
313+     }
314+ 
315+     object exception = context.attr (" get"  )(str (" exception"  ));
316+     object exc_info;
317+     if  (exception != object ())
318+     {
319+         exc_info = make_tuple (exception.attr (" __class__"  ), exception, exception.attr (" __traceback__"  ));
320+     }
321+     else 
322+     {
323+         exc_info = object (false );
324+     }
325+     if  (!PyObject_IsTrue (context.attr (" __contains__"  )(str (" source_traceback"  )).ptr ()) &&
326+         _exception_handler != object () &&
327+         _exception_handler.attr (" _source_traceback"  ) != object ())
328+     {
329+         context[" handle_traceback"  ] = _exception_handler.attr (" _source_traceback"  );
330+     }
331+ 
332+     list log_lines;
333+     log_lines.append (message);
334+     list context_keys (context.attr (" keys"  ));
335+     context_keys.sort ();
336+     for  (int  i = 0 ; i < len (context_keys); i++)
337+     {
338+         std::string key = extract<std::string>(context_keys[i]);
339+         if  (key == " message"   || key == " exception"  )
340+             continue ;
341+         str value (context[key]);
342+         if  (key == " source_traceback"  )
343+         {
344+             str tb = str (" "  ).join (_pymod_traceback.attr (" format_list"  )(value));
345+             value = str (" Object created at (most recent call last):\n "  );
346+             value += tb.rstrip ();
347+         }
348+         else  if  (key == " handle_traceback"  )
349+         {
350+             str tb = str (" "  ).join (_pymod_traceback.attr (" format_list"  )(value));
351+             value = str (" Handle created at (most recent call last):\n "  );
352+             value += tb.rstrip ();
353+         }
354+         else 
355+         {
356+             value = str (value.attr (" __str__"  )());
357+         }
358+         std::ostringstream stringStream;
359+         stringStream << key << " : "   << value;
360+         log_lines.append (str (stringStream.str ()));
361+     }
362+     list args;
363+     dict kwargs;
364+     args.append (str (" \n "  ).join (log_lines));
365+     kwargs[" exc_info"  ] = exc_info;
366+     _pymod_logger.attr (" error"  )(tuple (args), **kwargs);
367+ }
368+ 
369+ void  event_loop::call_exception_handler (object context)
370+ {
371+     if  (_exception_handler == object ())
372+     {
373+         try 
374+         {
375+             default_exception_handler (context);
376+         }
377+         catch  (const  error_already_set& e)
378+         {
379+             if  (PyErr_ExceptionMatches (PyExc_SystemExit)
380+                 || PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
381+             {
382+                 //  raise
383+             }
384+             else 
385+             {
386+                 PyErr_Clear ();
387+                 list args;
388+                 dict kwargs;
389+                 args.append (str (" Exception in default exception handler"  ));
390+                 kwargs[" exc_info"  ] = true ;
391+                 _pymod_logger.attr (" error"  )(tuple (args), **kwargs);
392+             }
393+         }
394+     }
395+     else 
396+     {
397+         try 
398+         {
399+             _exception_handler (context);
400+         }
401+         catch  (const  error_already_set& e)
402+         {
403+             if  (PyErr_ExceptionMatches (PyExc_SystemExit)
404+                 || PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
405+             {
406+                 //  raise
407+             }
408+             else 
409+             {
410+                 PyObject *ptype, *pvalue, *ptraceback;
411+                 PyErr_Fetch (&ptype, &pvalue, &ptraceback);
412+                 PyErr_NormalizeException (&ptype, &pvalue, &ptraceback);
413+                 object type (handle<>(ptype));
414+                 object value (handle<>(pvalue));
415+                 object traceback (handle<>(ptraceback));
416+                 try 
417+                 {
418+                     dict tmp_dict;
419+                     tmp_dict[" message"  ] = str (" Unhandled error in exception handler"  );
420+                     tmp_dict[" exception"  ] = value;
421+                     tmp_dict[" context"  ] = context;
422+                     default_exception_handler (tmp_dict);
423+                 }
424+                 catch  (const  error_already_set& e)
425+                 {
426+                     if  (PyErr_ExceptionMatches (PyExc_SystemExit)
427+                         || PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
428+                     {
429+                         //  raise
430+                     }
431+                     else 
432+                     {
433+                         boost::python::list args;
434+                         boost::python::dict kwargs;
435+                         args.append (str (" Exception in default exception handler"  ));
436+                         kwargs[" exc_info"  ] = true ;
437+                         _pymod_logger.attr (" error"  )(tuple (args), **kwargs);
438+                     }
439+                 }
440+             }
441+         }
442+     }
443+ }
444+ 
445+ 
284446}}}
0 commit comments