'Adds a task to be processed later.
Args:
target: A callable which should be processed by one of the workers.
args: A tuple of arguments to target.
name: The name of this task. Used to identify tasks in the log.
blocking: If True we block until the task is finished, otherwise we raise
Queue.Full
inline: If set, process the task inline when the queue is full. This
implies no blocking. Specifying inline helps if the worker tasks are
blocked because it still ensures some progress is made. However, this
can generally block the calling thread even after the threadpool is
available again and therefore decrease efficiency.
Raises:
Full() if the pool is full and can not accept new jobs.'

def AddTask(self, target, args, name='Unnamed    task', blocking=True, inline=True):

    if (self.max_threads == 0):
        target(*args)
        return
    if inline:
        blocking = False
    with self.lock:
        while True:
            try:
                self._queue.put((target, args, name, time.time()), block=False)
                return
            except Queue.Full:
                if ((len(self) < self.max_threads) and (self.CPUUsage() < 90)):
                    try:
                        self._AddWorker()
                        continue
                    except (RuntimeError, threading.ThreadError):
                        logging.error('Threadpool    exception:    Could    not    spawn    worker    threads.')
                if inline:
                    break
                elif blocking:
                    try:
                        self._queue.put((target, args, name, time.time()), block=True, timeout=1)
                        return
                    except Queue.Full:
                        continue
                else:
                    raise Full()
    if inline:
        target(*args)
