11"""Event loop and event loop policy."""
22
3- __all__ = ['AbstractEventLoopPolicy' , 'DefaultEventLoopPolicy' ,
3+ __all__ = ['AbstractEventLoopPolicy' ,
44 'AbstractEventLoop' , 'AbstractServer' ,
55 'Handle' , 'TimerHandle' ,
66 'get_event_loop_policy' , 'set_event_loop_policy' ,
77 'get_event_loop' , 'set_event_loop' , 'new_event_loop' ,
8+ 'get_child_watcher' , 'set_child_watcher' ,
89 ]
910
1011import subprocess
@@ -318,8 +319,18 @@ def new_event_loop(self):
318319 """XXX"""
319320 raise NotImplementedError
320321
322+ # Child processes handling (Unix only).
321323
322- class DefaultEventLoopPolicy (threading .local , AbstractEventLoopPolicy ):
324+ def get_child_watcher (self ):
325+ """XXX"""
326+ raise NotImplementedError
327+
328+ def set_child_watcher (self , watcher ):
329+ """XXX"""
330+ raise NotImplementedError
331+
332+
333+ class BaseDefaultEventLoopPolicy (AbstractEventLoopPolicy ):
323334 """Default policy implementation for accessing the event loop.
324335
325336 In this policy, each thread has its own event loop. However, we
@@ -332,41 +343,42 @@ class DefaultEventLoopPolicy(threading.local, AbstractEventLoopPolicy):
332343 associated).
333344 """
334345
335- _loop = None
336- _set_called = False
346+ _loop_factory = None
347+
348+ class _Local (threading .local ):
349+ _loop = None
350+ _set_called = False
351+
352+ def __init__ (self ):
353+ self ._local = self ._Local ()
337354
338355 def get_event_loop (self ):
339356 """Get the event loop.
340357
341358 This may be None or an instance of EventLoop.
342359 """
343- if (self ._loop is None and
344- not self ._set_called and
360+ if (self ._local . _loop is None and
361+ not self ._local . _set_called and
345362 isinstance (threading .current_thread (), threading ._MainThread )):
346- self ._loop = self .new_event_loop ()
347- assert self ._loop is not None , \
363+ self ._local . _loop = self .new_event_loop ()
364+ assert self ._local . _loop is not None , \
348365 ('There is no current event loop in thread %r.' %
349366 threading .current_thread ().name )
350- return self ._loop
367+ return self ._local . _loop
351368
352369 def set_event_loop (self , loop ):
353370 """Set the event loop."""
354- self ._set_called = True
371+ self ._local . _set_called = True
355372 assert loop is None or isinstance (loop , AbstractEventLoop )
356- self ._loop = loop
373+ self ._local . _loop = loop
357374
358375 def new_event_loop (self ):
359376 """Create a new event loop.
360377
361378 You must call set_event_loop() to make this the current event
362379 loop.
363380 """
364- if sys .platform == 'win32' : # pragma: no cover
365- from . import windows_events
366- return windows_events .SelectorEventLoop ()
367- else : # pragma: no cover
368- from . import unix_events
369- return unix_events .SelectorEventLoop ()
381+ return self ._loop_factory ()
370382
371383
372384# Event loop policy. The policy itself is always global, even if the
@@ -375,12 +387,22 @@ def new_event_loop(self):
375387# call to get_event_loop_policy().
376388_event_loop_policy = None
377389
390+ # Lock for protecting the on-the-fly creation of the event loop policy.
391+ _lock = threading .Lock ()
392+
393+
394+ def _init_event_loop_policy ():
395+ global _event_loop_policy
396+ with _lock :
397+ if _event_loop_policy is None : # pragma: no branch
398+ from . import DefaultEventLoopPolicy
399+ _event_loop_policy = DefaultEventLoopPolicy ()
400+
378401
379402def get_event_loop_policy ():
380403 """XXX"""
381- global _event_loop_policy
382404 if _event_loop_policy is None :
383- _event_loop_policy = DefaultEventLoopPolicy ()
405+ _init_event_loop_policy ()
384406 return _event_loop_policy
385407
386408
@@ -404,3 +426,13 @@ def set_event_loop(loop):
404426def new_event_loop ():
405427 """XXX"""
406428 return get_event_loop_policy ().new_event_loop ()
429+
430+
431+ def get_child_watcher ():
432+ """XXX"""
433+ return get_event_loop_policy ().get_child_watcher ()
434+
435+
436+ def set_child_watcher (watcher ):
437+ """XXX"""
438+ return get_event_loop_policy ().set_child_watcher (watcher )
0 commit comments