9
9
// 3. _ensure_fd_no_transport
10
10
// 4. _ensure_resolve
11
11
12
+ #include < iostream>
12
13
#include < boost/asio.hpp>
13
14
#include < boost/bind.hpp>
14
15
#include < boost/python.hpp>
@@ -53,6 +54,7 @@ void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future
53
54
// TODO: print the address
54
55
PyErr_SetString (PyExc_OSError, " Connect call failed {address}" );
55
56
}
57
+ prom.set_value ();
56
58
}
57
59
catch (const error_already_set& e)
58
60
{
@@ -67,15 +69,10 @@ void _sock_connect_cb(object pymod_socket, std::promise<void>& prom, std::future
67
69
{
68
70
// raise
69
71
}
70
- else if (PyErr_ExceptionMatches (PyExc_BaseException))
71
- {
72
- PyErr_Clear ();
73
- prom.set_exception (std::current_exception ());
74
- }
75
72
else
76
73
{
77
74
PyErr_Clear ();
78
- prom.set_value ( );
75
+ prom.set_exception ( std::current_exception () );
79
76
}
80
77
}
81
78
}
@@ -91,6 +88,7 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
91
88
conn = ret[0 ];
92
89
address = ret[1 ];
93
90
conn.attr (" setblocking" )(object (false ));
91
+ prom.set_value (make_tuple (conn, address));
94
92
}
95
93
catch (const error_already_set& e)
96
94
{
@@ -107,19 +105,27 @@ void _sock_accept(event_loop& loop, std::promise<object>& prom, std::future<obje
107
105
{
108
106
// raise
109
107
}
110
- else if (PyErr_ExceptionMatches (PyExc_BaseException))
111
- {
112
- PyErr_Clear ();
113
- prom.set_exception (std::current_exception ());
114
- }
115
108
else
116
109
{
117
110
PyErr_Clear ();
118
- prom.set_value ( make_tuple (conn, address ));
111
+ prom.set_exception ( std::current_exception ( ));
119
112
}
120
113
}
121
114
}
122
115
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
+
123
129
}
124
130
125
131
void 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)
237
243
try
238
244
{
239
245
sock.attr (" connect" )(address);
246
+ prom.set_value ();
240
247
}
241
248
catch (const error_already_set& e)
242
249
{
@@ -253,15 +260,10 @@ void event_loop::sock_connect(object sock, object address)
253
260
{
254
261
// raise
255
262
}
256
- else if (PyErr_ExceptionMatches (PyExc_BaseException))
257
- {
258
- PyErr_Clear ();
259
- prom.set_exception (std::current_exception ());
260
- }
261
263
else
262
264
{
263
265
PyErr_Clear ();
264
- prom.set_value ( );
266
+ prom.set_exception ( std::current_exception () );
265
267
}
266
268
}
267
269
fut.wait ();
@@ -281,4 +283,164 @@ void event_loop::sock_sendfile(object sock, object file, int offset, int count,
281
283
PyErr_SetString (PyExc_NotImplementedError, " Not implemented!" );
282
284
}
283
285
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
+
284
446
}}}
0 commit comments