def _run(self):
        # in_cpubound_thread is sentinel to prevent double thread dispatch
        context.get_context().thread_locals.in_cpubound_thread = True
        try:
            self.in_async = gevent.get_hub().loop.async()
            self.in_q_has_data = gevent.event.Event()
            self.in_async.start(self.in_q_has_data.set)
            while not self.stopping:
                if not self.in_q:
                    # wait for more work
                    self.in_q_has_data.clear()
                    self.in_q_has_data.wait()
                    continue
                # arbitrary non-preemptive service discipline can go here
                # FIFO for now, but we should experiment with others
                jobid, func, args, kwargs, enqueued = self.in_q.popleft()
                started = curtime()
                try:
                    ret = self.results[jobid] = func(*args, **kwargs)
                except Exception as e:
                    ret = self.results[jobid] = self._Caught(e)
                self.out_q.append(jobid)
                self.out_async.send()
                # keep track of some statistics
                queued, duration = started - enqueued, curtime() - started
                size = None
                # ret s set up above before async send
                if hasattr(ret, '__len__') and callable(ret.__len__):
                    size = len(ret)
                _queue_stats('cpu_bound', func.__name__, queued, duration, size)
        except:
            self._error()
            # this may always halt the server process
dataset/ETHPy150Open paypal/support/support/async.py/CPUThread._run/original