<commit_before>from __future__ import unicode_literals
from prompt_toolkit.utils import is_windows
from .base import EventLoop

__all__ = (
    'create_event_loop',
    'create_asyncio_event_loop',
    'use_asyncio_event_loop',
    'get_event_loop',
    'set_event_loop',
    'run_in_executor',
    'call_from_executor',
    'run_until_complete',
)


def create_event_loop(inputhook=None, recognize_win32_paste=True):
    """
    Create and return an
    :class:`~prompt_toolkit.eventloop.base.EventLoop` instance.
    """
    if is_windows():
        from .win32 import Win32EventLoop
        return Win32EventLoop(inputhook=inputhook, recognize_paste=recognize_win32_paste)
    else:
        from .posix import PosixEventLoop
        return PosixEventLoop(inputhook=inputhook)


def create_asyncio_event_loop(loop=None):
    """
    Returns an asyncio :class:`~prompt_toolkit.eventloop.EventLoop` instance
    for usage in a :class:`~prompt_toolkit.application.Application`. It is a
    wrapper around an asyncio loop.

    :param loop: The asyncio eventloop (or `None` if the default asyncioloop
                 should be used.)
    """
    # Inline import, to make sure the rest doesn't break on Python 2. (Where
    # asyncio is not available.)
    if is_windows():
        from prompt_toolkit.eventloop.asyncio_win32 import Win32AsyncioEventLoop as AsyncioEventLoop
    else:
        from prompt_toolkit.eventloop.asyncio_posix import PosixAsyncioEventLoop as AsyncioEventLoop

    return AsyncioEventLoop(loop)


def use_asyncio_event_loop(loop=None):
    """
    Use the asyncio event loop for prompt_toolkit applications.
    """
    set_event_loop(create_asyncio_event_loop(loop))


_loop = None


def get_event_loop():
    """
    Return the current event loop.
    This has to be called after setting an event loop, using `set_event_loop`.
    (Unline Asyncio, we don't set a default loop.)
    """
    # When this function is called for the first time, and no loop has been
    # set: create one.
    global _loop
    if _loop is None:
        _loop = create_event_loop()

    return _loop


def set_event_loop(loop):
    """
    Set the current event loop.

    :param loop: `EventLoop` instance or None. (Pass `None` to clear the
        current loop.)
    """
    assert loop is None or isinstance(loop, EventLoop)
    global _loop
    _loop = loop


def run_in_executor(callback, _daemon=False):
    """
    Run a long running function in a background thread.
    """
    return get_event_loop().run_in_executor(callback, _daemon=_daemon)


def call_from_executor(callback, _max_postpone_until=None):
    """
    Call this function in the main event loop.
    """
    return get_event_loop().call_from_executor(
        callback, _max_postpone_until=_max_postpone_until)


def run_until_complete(future):
    """
    Keep running until this future has been set.
    Return the Future's result, or raise its exception.
    """
    return get_event_loop().run_until_complete(future)
<commit_msg>Fixed race condition in 'get_event_loop'. Added lock.<commit_after>from __future__ import unicode_literals
from prompt_toolkit.utils import is_windows
from .base import EventLoop
import threading

__all__ = (
    'create_event_loop',
    'create_asyncio_event_loop',
    'use_asyncio_event_loop',
    'get_event_loop',
    'set_event_loop',
    'run_in_executor',
    'call_from_executor',
    'run_until_complete',
)


def create_event_loop(inputhook=None, recognize_win32_paste=True):
    """
    Create and return an
    :class:`~prompt_toolkit.eventloop.base.EventLoop` instance.
    """
    if is_windows():
        from .win32 import Win32EventLoop
        return Win32EventLoop(inputhook=inputhook, recognize_paste=recognize_win32_paste)
    else:
        from .posix import PosixEventLoop
        return PosixEventLoop(inputhook=inputhook)


def create_asyncio_event_loop(loop=None):
    """
    Returns an asyncio :class:`~prompt_toolkit.eventloop.EventLoop` instance
    for usage in a :class:`~prompt_toolkit.application.Application`. It is a
    wrapper around an asyncio loop.

    :param loop: The asyncio eventloop (or `None` if the default asyncioloop
                 should be used.)
    """
    # Inline import, to make sure the rest doesn't break on Python 2. (Where
    # asyncio is not available.)
    if is_windows():
        from prompt_toolkit.eventloop.asyncio_win32 import Win32AsyncioEventLoop as AsyncioEventLoop
    else:
        from prompt_toolkit.eventloop.asyncio_posix import PosixAsyncioEventLoop as AsyncioEventLoop

    return AsyncioEventLoop(loop)


def use_asyncio_event_loop(loop=None):
    """
    Use the asyncio event loop for prompt_toolkit applications.
    """
    set_event_loop(create_asyncio_event_loop(loop))


_loop = None
_loop_lock = threading.RLock()


def get_event_loop():
    """
    Return the current event loop.
    This will create a new loop if no loop was set yet.
    """
    # When this function is called for the first time, and no loop has been
    # set: create one.
    global _loop

    with _loop_lock:
        # The following two lines are not atomic. I ended up in a situation
        # where two threads were calling `get_event_loop()` at the same time,
        # and that way we had two event loop instances. On one of the
        # instances, `call_from_executor` was called, but never executed
        # because that loop was not running.
        if _loop is None:
            _loop = create_event_loop()

        return _loop


def set_event_loop(loop):
    """
    Set the current event loop.

    :param loop: `EventLoop` instance or None. (Pass `None` to clear the
        current loop.)
    """
    assert loop is None or isinstance(loop, EventLoop)
    global _loop
    _loop = loop


def run_in_executor(callback, _daemon=False):
    """
    Run a long running function in a background thread.
    """
    return get_event_loop().run_in_executor(callback, _daemon=_daemon)


def call_from_executor(callback, _max_postpone_until=None):
    """
    Call this function in the main event loop.
    """
    return get_event_loop().call_from_executor(
        callback, _max_postpone_until=_max_postpone_until)


def run_until_complete(future):
    """
    Keep running until this future has been set.
    Return the Future's result, or raise its exception.
    """
    return get_event_loop().run_until_complete(future)

{'fraction_non_alphanumeric': 0.07829070492825951, 'fraction_numerical': 0.004678727386150967, 'mean_word_length': 3.386456908344733, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '913466', 'n_tokens_mistral': 1996, 'n_tokens_neox': 1929, 'n_words': 577}