def fire(self, *args, **kw):
        result = []
        with self._hlock:
            handlers = self.handlers
        if self.threads == 0:
            for k in handlers:
                h, m, t = handlers[k]
                try:
                    r = self._memoize(h, m, t, *args, **kw)
                    result.append(tuple(r))
                except:
                    result.append((False, self._error(sys.exc_info()), h))
        elif self.threads > 0:
            queue = Queue()
            rlock = RLock()
            def _execute(*args, **kw):
                while True:
                    try:
                        item = queue.get()
                        if item is None:
                            queue.task_done()
                            break
                        h, m, t = handlers[item]
                        try:
                            r = self._memoize(h, m, t, *args, **kw)
                            if not self.asynch:
                                with rlock:
                                    result.append(tuple(r))
                        except:
                            if not self.asynch:
                                with rlock:
                                    result.append((False, self._error(sys.exc_info()), h))
                        queue.task_done()
                    except Empty:
                        break
            if handlers:
                threads = self._threads(handlers=handlers)
                for _ in range(threads):
                    t = Thread(target=_execute, args=args, kwargs=kw)
                    t.daemon = True
                    t.start()
                for k in handlers:
                    queue.put(k)
                    if self.asynch:
                        h, _, _ = handlers[k]
                        result.append((None, None, h))
                for _ in range(threads):
                    queue.put(None)
                if not self.asynch:
                    queue.join()
        return tuple(result) or None