# Path: lib/task/task.py
# class Task(object):
# 
#     def __init__(self, future, fn, args, kwargs):
#         self._future = future   # type: concurrent.futures.Future
#         self._fn = fn           # type: callable
#         self._args = args
#         self._kwargs = kwargs
# 
#     def run(self):
#         if not self._future.set_running_or_notify_cancel():
#             # cancelled, skip it
#             return
# 
#         logger.debug('starting task: %r', self)
# 
#         try:
#             result = self._fn(*self._args, **self._kwargs)
#         except Exception as exception:
#             self._future.set_exception(exception)
#         except:     # noqa: E722
#             # failure - old style exceptions
#             exception = sys.exc_info()[1]
#             self._future.set_exception(exception)
#         else:
#             # success - set result
#             self._future.set_result(result)
# 
#         logger.debug('finished task: %r', self)
# 
#     def __repr__(self):
#         return '%s(%r)' % ('Task', {
#             'future': self._future,
#             'fn': self._fn,
#             'args': self._args,
#             'kwargs': self._kwargs,
#         })
# 
# Path: lib/task/worker.py
# def spawn_worker(pool, name=None):
#     if name is not None and not isinstance(name, str):
#         raise TypeError('name must be a str: %r' % (name))
# 
#     worker_instance = Worker(pool)
# 
#     def run_worker():
#         try:
#             worker_instance.run()
#         except Exception as e:
#             logger.error(
#                 'unhandled exception during worker thread loop: %r', e,
#             )
# 
#         # explicitly delete references since worker is about to exit:
#         worker_instance.clear()
# 
#     worker_thread = threading.Thread(target=run_worker, name=name)
#     worker_thread.daemon = True
# 
#     worker_instance.handle = worker_thread
#     logger.debug('created worker: %r', worker_instance)
# 
#     worker_thread.start()
#     return worker_instance
# 
# Path: lib/util/id.py
# def generate_id(prefix=None):
#     '''
#     Generates and returns a `str` id.
# 
#     The id is generated by appending the `prefix` to a globally unique integer
#     counter. The counter is not specific to the prefix.
#     '''
#     if not isinstance(prefix, str):
#         raise TypeError('prefix must be a str: %r' % (prefix))
# 
#     if prefix is None:
#         prefix = ''
# 
#     current_count = _get_counter()
#     _increment_counter()
# 
#     return '%s%d' % (prefix, current_count)
# 
# Path: lib/util/sys.py
# def get_cpu_count():
#     ''' Returns the core count of the current system. '''
#     try:
#         return multiprocessing.cpu_count()
#     except (AttributeError, NotImplementedError):
#         return 1


from concurrent.futures import _base as futurebase
from ..task.task import Task
from ..task.worker import spawn_worker
from ..util.id import generate_id
from ..util.sys import get_cpu_count
import logging
import queue
import threading
#!/usr/bin/env python3

'''
lib/task/pool.py
Task pool abstraction. Replacement for `concurrent.futures`.

Defines a task pool class that can be used to run tasks asynchronously.

Most of this logic was taken from pythonfutures:
https://github.com/agronholm/pythonfutures
https://git.io/vdCQ2
'''



logger = logging.getLogger('sublime-ycmd.' + __name__)


class Pool(object):
    '''
    Task pool. Schedules work to run in a thread pool.

    This class conforms to `concurrent.futures.Executor`. It does not use
    weak references, however, so it is expected that the application shuts down
    the pool properly. Worker threads are created as daemons, so they won't
    stop the program from shutting down.
    '''

    def __init__(self, max_workers=None, thread_name_prefix=''):
        if max_workers is None:

# Path: lib/task/task.py
# class Task(object):
# 
#     def __init__(self, future, fn, args, kwargs):
#         self._future = future   # type: concurrent.futures.Future
#         self._fn = fn           # type: callable
#         self._args = args
#         self._kwargs = kwargs
# 
#     def run(self):
#         if not self._future.set_running_or_notify_cancel():
#             # cancelled, skip it
#             return
# 
#         logger.debug('starting task: %r', self)
# 
#         try:
#             result = self._fn(*self._args, **self._kwargs)
#         except Exception as exception:
#             self._future.set_exception(exception)
#         except:     # noqa: E722
#             # failure - old style exceptions
#             exception = sys.exc_info()[1]
#             self._future.set_exception(exception)
#         else:
#             # success - set result
#             self._future.set_result(result)
# 
#         logger.debug('finished task: %r', self)
# 
#     def __repr__(self):
#         return '%s(%r)' % ('Task', {
#             'future': self._future,
#             'fn': self._fn,
#             'args': self._args,
#             'kwargs': self._kwargs,
#         })
# 
# Path: lib/task/worker.py
# def spawn_worker(pool, name=None):
#     if name is not None and not isinstance(name, str):
#         raise TypeError('name must be a str: %r' % (name))
# 
#     worker_instance = Worker(pool)
# 
#     def run_worker():
#         try:
#             worker_instance.run()
#         except Exception as e:
#             logger.error(
#                 'unhandled exception during worker thread loop: %r', e,
#             )
# 
#         # explicitly delete references since worker is about to exit:
#         worker_instance.clear()
# 
#     worker_thread = threading.Thread(target=run_worker, name=name)
#     worker_thread.daemon = True
# 
#     worker_instance.handle = worker_thread
#     logger.debug('created worker: %r', worker_instance)
# 
#     worker_thread.start()
#     return worker_instance
# 
# Path: lib/util/id.py
# def generate_id(prefix=None):
#     '''
#     Generates and returns a `str` id.
# 
#     The id is generated by appending the `prefix` to a globally unique integer
#     counter. The counter is not specific to the prefix.
#     '''
#     if not isinstance(prefix, str):
#         raise TypeError('prefix must be a str: %r' % (prefix))
# 
#     if prefix is None:
#         prefix = ''
# 
#     current_count = _get_counter()
#     _increment_counter()
# 
#     return '%s%d' % (prefix, current_count)
# 
# Path: lib/util/sys.py
# def get_cpu_count():
#     ''' Returns the core count of the current system. '''
#     try:
#         return multiprocessing.cpu_count()
#     except (AttributeError, NotImplementedError):
#         return 1


# Path: lib/task/pool.py
from concurrent.futures import _base as futurebase
from ..task.task import Task
from ..task.worker import spawn_worker
from ..util.id import generate_id
from ..util.sys import get_cpu_count
import logging
import queue
import threading

#!/usr/bin/env python3

'''
lib/task/pool.py
Task pool abstraction. Replacement for `concurrent.futures`.

Defines a task pool class that can be used to run tasks asynchronously.

Most of this logic was taken from pythonfutures:
https://github.com/agronholm/pythonfutures
https://git.io/vdCQ2
'''



logger = logging.getLogger('sublime-ycmd.' + __name__)


class Pool(object):
    '''
    Task pool. Schedules work to run in a thread pool.

    This class conforms to `concurrent.futures.Executor`. It does not use
    weak references, however, so it is expected that the application shuts down
    the pool properly. Worker threads are created as daemons, so they won't
    stop the program from shutting down.
    '''

    def __init__(self, max_workers=None, thread_name_prefix=''):
        if max_workers is None:

            max_workers = (get_cpu_count() or 1) * 5