def get_global_tor(reactor, control_port=None, progress_updates=None, _tor_launcher=lambda r, c, p: launch_tor( c, r, progress_updates=p)): """ See description of :class:`txtorcon.TCPHiddenServiceEndpoint`'s class-method ``global_tor`` :param control_port: a TCP port upon which to run the launched Tor's control-protocol (selected by the OS by default). :param progress_updates: A callable that takes 3 args: ``percent, tag, message`` which is called when Tor announcing some progress setting itself up. :returns: a ``Deferred`` that fires a :class:`txtorcon.TorConfig` which is bootstrapped. The _tor_launcher keyword arg is internal-only. """ global _global_tor_config global _global_tor_lock yield _global_tor_lock.acquire() try: if _global_tor_config is None: _global_tor_config = config = yield _create_default_config(reactor) # start Tor launching yield _tor_launcher(reactor, config, progress_updates) yield config.post_bootstrap else: cp = _global_tor_config.ControlPort if control_port is not None and control_port != cp: raise RuntimeError( "ControlPort is %s, you wanted %s" % (cp, control_port)) defer.returnValue(_global_tor_config) finally: _global_tor_lock.release()
def _launch(control_port): config = yield _create_default_config(reactor, control_port) yield launch_tor(config, reactor, progress_updates=progress) yield config.post_bootstrap defer.returnValue(config)