Example #1
0
    def get(self):
        logging.info('started; imp.lock_held:%s', imp.lock_held())
        # flush to prove the code started running
        logservice.flush()

        with _LOCK:
            # run a thread which will hold the import lock until we release _LOCK
            thread = threading.Thread(target=hold_import_lock)
            thread.start()

            # wait for the thread to be blocked
            logging.info('waiting for import lock to be held by thread ...')
            is_set = _WAITING_FOR_LOCK.wait(30)
            if not is_set:
                raise Exception(
                    '_WAITING_FOR_LOCK not set: the module was already imported; this only works on the first call'
                )
            logging.info('done; imp.lock_held:%s', imp.lock_held())
            # flush logs: will hang forever due to the call to group.lengthString(...)
            logservice.flush()

        logging.info('lock released')
        thread.join()
        logging.info('all done')

        self.response.write('OK!')
        _WAITING_FOR_LOCK.clear()
Example #2
0
    def test_waiting_during_different_thread_importing(self):
        """
        EventualResult.wait() should work if called while a module is
        being imported in a different thread. See
        EventualResultTests.test_noWaitingDuringImport for the explanation of
        what should happen if an import is happening in the current thread.
        """
        test_complete = threading.Event()
        lock_held = threading.Event()
        er = EventualResult(succeed(123), None)

        def other_thread():
            imp.acquire_lock()
            lock_held.set()
            test_complete.wait()
            imp.release_lock()

        t = threading.Thread(target=other_thread)
        t.start()
        lock_held.wait()

        # While the imp lock is held by the other thread, we can't
        # allow exceptions/assertions to happen because trial will
        # try to do an import causing a deadlock instead of a
        # failure. We collect all assertion pairs (result, expected),
        # wait for the import lock to be released, and then check our
        # assertions at the end of the test.
        assertions = []

        if hasattr(sys, 'pypy_version_info'):
            # Under PyPy imp.lock_held only returns True if the current thread
            # holds the lock. If/When that bug is fixed, this assertion
            # should fail and we should remove this special casing.
            # See: http://stackoverflow.com/q/23816549/132413
            assertions.append((imp.lock_held(), False))
        else:
            # we want to run .wait while the other thread has the lock acquired
            assertions.append((imp.lock_held(), True))
            try:
                assertions.append((er.wait(), 123))
            finally:
                test_complete.set()

            assertions.append((imp.lock_held(), True))

        test_complete.set()

        t.join()

        [self.assertEqual(result, expected) for result, expected in assertions]
Example #3
0
    def test_manual_locking(self):
        import thread, os, imp, time, sys
        f = open(os.path.join(self.tmpdir, 'foobaz2.py'), 'w')
        f.close()  # empty
        done = []

        def f():
            sys.path.insert(0, self.tmpdir)
            import foobaz2
            p = sys.path.pop(0)
            assert p == self.tmpdir
            done.append(1)

        assert not imp.lock_held()
        imp.acquire_lock()
        assert imp.lock_held()
        thread.start_new_thread(f, ())
        time.sleep(0.9)
        assert not done
        assert imp.lock_held()
        # check that it's a recursive lock
        imp.acquire_lock()
        assert imp.lock_held()
        imp.acquire_lock()
        assert imp.lock_held()
        imp.release_lock()
        assert imp.lock_held()
        imp.release_lock()
        assert imp.lock_held()
        imp.release_lock()
        assert not imp.lock_held()
        self.waitfor(lambda: done)
        assert done
Example #4
0
 def test_manual_locking(self):
     import thread, os, imp, time, sys
     f = open(os.path.join(self.tmpdir, 'foobaz2.py'), 'w')
     f.close()   # empty
     done = []
     def f():
         sys.path.insert(0, self.tmpdir)
         import foobaz2
         p = sys.path.pop(0)
         assert p == self.tmpdir
         done.append(1)
     assert not imp.lock_held()
     imp.acquire_lock()
     assert imp.lock_held()
     thread.start_new_thread(f, ())
     time.sleep(0.9)
     assert not done
     assert imp.lock_held()
     # check that it's a recursive lock
     imp.acquire_lock()
     assert imp.lock_held()
     imp.acquire_lock()
     assert imp.lock_held()
     imp.release_lock()
     assert imp.lock_held()
     imp.release_lock()
     assert imp.lock_held()
     imp.release_lock()
     assert not imp.lock_held()
     self.waitfor(lambda: done)
     assert done
Example #5
0
    def test_waiting_during_different_thread_importing(self):
        """
        EventualResult.wait() should work if called while a module is
        being imported in a different thread. See
        EventualResultTests.test_noWaitingDuringImport for the explanation of
        what should happen if an import is happening in the current thread.
        """
        test_complete = threading.Event()
        lock_held = threading.Event()
        er = EventualResult(succeed(123), None)

        def other_thread():
            imp.acquire_lock()
            lock_held.set()
            test_complete.wait()
            imp.release_lock()

        t = threading.Thread(target=other_thread)
        t.start()
        lock_held.wait()

        # While the imp lock is held by the other thread, we can't
        # allow exceptions/assertions to happen because trial will
        # try to do an import causing a deadlock instead of a
        # failure. We collect all assertion pairs (result, expected),
        # wait for the import lock to be released, and then check our
        # assertions at the end of the test.
        assertions = []

        if hasattr(sys, 'pypy_version_info'):
            # Under PyPy imp.lock_held only returns True if the current thread
            # holds the lock. If/When that bug is fixed, this assertion
            # should fail and we should remove this special casing.
            # See: http://stackoverflow.com/q/23816549/132413
            assertions.append((imp.lock_held(), False))
        else:
            # we want to run .wait while the other thread has the lock acquired
            assertions.append((imp.lock_held(), True))
            try:
                assertions.append((er.wait(), 123))
            finally:
                test_complete.set()

            assertions.append((imp.lock_held(), True))

        test_complete.set()

        t.join()

        [self.assertEqual(result, expected) for result, expected in assertions]
Example #6
0
	def _load_plugins(self):
		# Get a list of all plugins... (ignoring any names starting with _)
		# TODO use a more readable expression like:
		# [d for d in ... if ...]
		#self._plugins = dict(map(lambda x: (os.path.basename(x)[:-3], None), glob(plugins.__path__[0] + '/[!_]*.py')))
		
		self._plugins = dict([ (os.path.basename(x)[:-3], None)
						for x in glob(plugins.__path__[0] + '/[!_]*.py') ])
		
		# and load any that are not yet loaded.
		# Don't attempt to reload existing ones even if they might have changed,
		# because I don't know what the consequences be:)
		try: 
			for plugin in self._plugins.keys():
				if not sys.modules.has_key('iobserver.plugins.'+plugin):
					# Load new plugin
					imp.acquire_lock()
					
					found = imp.find_module(plugin, plugins.__path__)
					self._plugins[plugin] = imp.load_module('iobserver.plugins.'+plugin, found[0], found[1], found[2])
					
					imp.release_lock()
				
				else:
					# Reload plugin
					reload(sys.modules['iobserver.plugins.'+plugin])
		except Exception, data:
			if imp.lock_held(): imp.release_lock()
			if self._thread.isAlive():
				iObserverError(self, "Could not load plugin(s): %s" % data)
			else:
				raise iObserverError(None, "Could not load plugin(s): %s" % data)
def applog_handle_patched(self, record):
    '''
    Monkey-patch to avoid deadlock in google.appengine.api.app_logging.AppLogsHandler.

    A rare deadlock is possible because flushing the logs holds this handler's lock, as well as
    the _LogsDequeBuffer's lock. It then blocks on the import lock as part of the native
    protocol buffer library for some mysterious reason. Meanwhile, if another thread executes an
    import that then logs something, it holds the import lock and blocks on the log lock.

    To avoid it: we try to acquire the log lock. If it fails, we test if import lock is held.
    If it is, we might deadlock: If this thread holds the import lock, it is not safe
    to wait for the log lock. Instead, we drop the log message. I did add a task queue
    message in a previous version, so I know that this does get hit occasionally.

    For details, see: https://github.com/evanj/app-engine-log-deadlock
    '''
    # Modified from the version in logging.Handler.handle
    rv = self.filter(record)
    if rv:
        # attempt to acquire the lock in a non-blocking fashion to detect deadlocks
        acquired = self.lock.acquire(False)
        if not acquired:
            if imp.lock_held():
                # this thread MIGHT hold the import lock (some other thread might also)
                # it is not safe to block: if we hold the import lock, the thread holding the
                # log lock will deadlock if it tries to flush
                return rv
            # safe to block: this thread does not hold the import lock
            self.lock.acquire()
        try:
            self.emit(record)
        finally:
            self.lock.release()
    return rv
Example #8
0
 def do(self):
     if imp.lock_held() is True:
         # inject global variables instead of rewriting the file
         self.do_inject()
     else:
         # just rewrite
         self.do_rewrite()
Example #9
0
    def wait(self, timeout=None):
        """
        Return the result, or throw the exception if result is a failure.

        It may take an unknown amount of time to return the result, so a
        timeout option is provided. If the given number of seconds pass with
        no result, a TimeoutError will be thrown.

        If a previous call timed out, additional calls to this function will
        still wait for a result and return it if available. If a result was
        returned or raised on one call, additional calls will return/raise the
        same result.
        """
        if threadable.isInIOThread():
            raise RuntimeError(
                "EventualResult.wait() must not be run in the reactor thread.")

        if imp.lock_held():
            # If EventualResult.wait() is run during module import, if the
            # Twisted code that is being run also imports something the result
            # will be a deadlock. Even if that is not an issue it would
            # prevent importing in other threads until the call returns.
            raise RuntimeError(
                "EventualResult.wait() must not be run at module import time.")

        result = self._result(timeout)
        if isinstance(result, Failure):
            result.raiseException()
        return result
Example #10
0
        def g(*a, **kw):
            enqueued = curtime()
            ctx = context.get_context()
            started = []

            def in_thread(*a, **kw):
                ml.ld3("In thread {0}", f.__name__)
                started.append(curtime())
                return f(*a, **kw)

            # some modules import things lazily; it is too dangerous
            # to run a function in another thread if the import lock is
            # held by the current thread (this happens rarely -- only
            # if the thread dispatched function is being executed at
            # the import time of a module)
            if not ctx.cpu_thread_enabled or imp.lock_held():
                ret = in_thread(*a, **kw)
            elif in_threadpool() is self.pool:
                ret = in_thread(*a, **kw)
            else:
                ctx.stats[self.name + '.depth'].add(1 + len(self.pool))
                ret = self.pool.apply_e((Exception,), in_thread, a, kw)
                ml.ld3("Enqueued to thread {0}/depth {1}", f.__name__, len(pool))
            start = started[0]
            duration = curtime() - start
            queued = start - enqueued
            if hasattr(ret, '__len__') and callable(ret.__len__):
                prsize = ret.__len__()  # parameter-or-return size
            elif a and hasattr(a[0], '__len__') and callable(a[0].__len__):
                prsize = a[0].__len__()
            else:
                prsize = None
            _queue_stats(name, f.__name__, queued, duration, prsize)
            return ret
def import_function(pkgmodfunc):
    steps = pkgmodfunc.split('.')
    if len(steps) in (0, 1):
        return None
    funcname = steps.pop()

    if not imp.lock_held():
        imp.acquire_lock()

    path = None
    try:
        for step in steps:
            (fil, filename, (suffix, mode, typ)) = imp.find_module(step, path)
            module = imp.load_module(step, fil, filename, (suffix, mode, typ))
            if hasattr(module, '__path__'):
                path = module.__path__
            else:
                if not hasattr(module, funcname):
                    raise ImportError(pkgmodfunc)
                try:
                    return getattr(module, funcname)
                except AttributeError:
                    raise ImportError(pkgmodfunc)
    finally:
        imp.release_lock()
Example #12
0
 def do(self, run=False):
     if imp.lock_held() is True:
         # inject global variables instead of rewriting the file
         self.do_inject()
     else:
         # just rewrite
         self.do_rewrite(run=run)
Example #13
0
        def __enter__(self):
            if self.sync or imp.lock_held():
# Some modules like nosetests, coverage etc
#   python -m unittest test_xxx.py  or  nosetests test_xxx.py
# hang when Python multi-threading was used in the import stage due to (Python
# import lock) bug in the threading module.  See also
# https://github.com/paramiko/paramiko/issues/104
# https://docs.python.org/2/library/threading.html#importing-in-threaded-code
# Disable the asynchoronous mode for safe importing
                def def_async_fn(fn):
                    return fn

            else:
                # Enable back-ground mode
                def def_async_fn(fn):
                    def async_fn(*args, **kwargs):
                        if self.handler is not None:
                            self.handler.join()
                        self.handler = ThreadWithTraceBack(target=fn, args=args,
                                                           kwargs=kwargs)
                        self.handler.start()
                        return self.handler
                    return async_fn

            if len(self.fns) == 1:
                return def_async_fn(self.fns[0])
            else:
                return [def_async_fn(fn) for fn in self.fns]
Example #14
0
    def load(self, name, notify=True):
        """
        Load a plugin.
        """
        if name in self.plugins:
            self.unload(name)

        try:
            if name in self.modules:
                imp.acquire_lock()
                module = imp.reload(self.modules[name])
                imp.release_lock()
            else:
                file, filename, info = imp.find_module(name, [plugins_dir, default_plugin_path])
                imp.acquire_lock()
                module = imp.load_module(name, file, filename, info)
                imp.release_lock()
        except Exception as e:
            import traceback
            log.debug("Could not load plugin: \n%s", traceback.format_exc())
            self.core.information("Could not load plugin: %s" % e, 'Error')
            return
        finally:
            if imp.lock_held():
                imp.release_lock()

        self.modules[name] = module
        self.commands[name] = {}
        self.keys[name] = {}
        self.tab_keys[name] = {}
        self.tab_commands[name] = {}
        self.event_handlers[name] = []
        self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir)
        if notify:
            self.core.information('Plugin %s loaded' % name, 'Info')
    def run(self, threadrunlimit=None):
        """
        threadrunlimit: only run this many threads at most total,
                        if None (default) then run all threads
        """
        runcount = len(self.threads[self.next_thread:])
        if threadrunlimit is not None:
            runcount = min(runcount, threadrunlimit)

        next_thread = 0
        while runcount > 0:
            batch = self.threads[next_thread:next_thread + self.maxparallel]

            # cannot start threads while imp lock is held.
            toLock = imp.lock_held()
            if toLock:
                imp.release_lock()

            # Start all threads in this batch
            for thread in batch:
                thread.start()

            # Wait for them all to finish
            for thread in batch:
                thread.join

            # rest lock state
            if toLock:
                imp.acquire_lock()

            runcount = runcount - len(batch)
            next_thread = next_thread + len(batch)
Example #16
0
    def wait(self, timeout=None):
        """
        Return the result, or throw the exception if result is a failure.
        It may take an unknown amount of time to return the result, so a
        timeout option is provided. If the given number of seconds pass with
        no result, a TimeoutError will be thrown.
        If a previous call timed out, additional calls to this function will
        still wait for a result and return it if available. If a result was
        returned or raised on one call, additional calls will return/raise the
        same result.
        """

        if imp.lock_held():
            try:
                imp.release_lock()
            except RuntimeError:
                # The lock is held by some other thread. We should be safe
                # to continue.
                pass
            else:
                # If EventualResult.wait() is run during module import, if the
                # Twisted code that is being run also imports something the result
                # will be a deadlock. Even if that is not an issue it would
                # prevent importing in other threads until the call returns.
                raise RuntimeError(
                    "EventualResult.wait() must not be run at module import time.")

        try:
            result = self._result(timeout)
        except TimeoutError:
            raise
        if isinstance(result, Failure):
            result.raiseException()
            pass
        return result
Example #17
0
 def post_process(self):
     if self.input == self.output and self.__inputBuffer == self.__outputBuffer:
         return
     try:
         # open file for output (no auto-run)
         if self.output != '':
             self.run = False
             output_file = open(self.output, 'w')           
         # open tmp file
         else:
             self.run = True
             self.output = 'tmp_' + os.path.basename(self.input)
             output_file = open(self.output, 'w')
         # write post-processed code to file
         output_file.write(self.__outputBuffer)
     finally:
         output_file.close()            
     # resolve postprocess stage depending on the mode
     if self.run == False:
         return
     else:    
         # if this module is loaded as a library override the import
         if imp.lock_held() is True:
                 self.override_import()
         else:
             self.on_the_fly()
             # break execution so python doesn't
             # run the rest of the pre-processed code
             return
Example #18
0
def execute(meth, *args, **kwargs):
    """
    Execute *meth* in a Python thread, blocking the current coroutine/
    greenthread until the method completes.

    The primary use case for this is to wrap an object or module that is not
    amenable to monkeypatching or any of the other tricks that Eventlet uses
    to achieve cooperative yielding.  With tpool, you can force such objects to
    cooperate with green threads by sticking them in native threads, at the cost
    of some overhead.
    """
    setup()
    # if already in tpool, don't recurse into the tpool
    # also, call functions directly if we're inside an import lock, because
    # if meth does any importing (sadly common), it will hang
    my_thread = threading.currentThread()
    if my_thread in _threads or imp.lock_held() or _nthreads == 0:
        return meth(*args, **kwargs)

    e = event.Event()
    _reqq.put((e, meth, args, kwargs))

    rv = e.wait()
    if isinstance(rv, tuple) \
            and len(rv) == 3 \
            and isinstance(rv[1], EXC_CLASSES):
        (c, e, tb) = rv
        if not QUIET:
            traceback.print_exception(c, e, tb)
            traceback.print_stack()
        six.reraise(c, e, tb)
    return rv
Example #19
0
 def other_thread():
     imp.acquire_lock()  # 3
     assert imp.lock_held()
     lock_held.release()  # 4
     test_complete.acquire()  # 7
     imp.release_lock()  # 8
     lock_released.release()  # 9
Example #20
0
    def testLock(self):
        LOOPS = 50

        # The import lock may already be held, e.g. if the test suite is run
        # via "import test.autotest".
        lock_held_at_start = imp.lock_held()
        self.verify_lock_state(lock_held_at_start)

        for i in range(LOOPS):
            imp.acquire_lock()
            self.verify_lock_state(True)

        for i in range(LOOPS):
            imp.release_lock()

        # The original state should be restored now.
        self.verify_lock_state(lock_held_at_start)

        if not lock_held_at_start:
            try:
                imp.release_lock()
            except RuntimeError:
                pass
            else:
                self.fail("release_lock() without lock should raise "
                          "RuntimeError")
Example #21
0
        def view_import(name, globals={}, locals={}, fromlist=[], level=0):
            """the drop-in replacement for __import__, that optionally imports
            locally as well.
            """
            # don't override nested imports
            save_import = builtin_mod.__import__
            builtin_mod.__import__ = local_import

            if imp.lock_held():
                # this is a side-effect import, don't do it remotely, or even
                # ignore the local effects
                return local_import(name, globals, locals, fromlist, level)

            imp.acquire_lock()
            if local:
                mod = local_import(name, globals, locals, fromlist, level)
            else:
                raise NotImplementedError("remote-only imports not yet implemented")
            imp.release_lock()

            key = name+':'+','.join(fromlist or [])
            if level <= 0 and key not in modules:
                modules.add(key)
                if not quiet:
                    if fromlist:
                        print("importing %s from %s on engine(s)"%(','.join(fromlist), name))
                    else:
                        print("importing %s on engine(s)"%name)
                results.append(self.apply_async(remote_import, name, fromlist, level))
            # restore override
            builtin_mod.__import__ = save_import

            return mod
Example #22
0
    def check_parallel_module_init(self):
        if imp.lock_held():
            # This triggers on, e.g., from test import autotest.
            raise unittest.SkipTest("can't run when import lock is held")

        done = threading.Event()
        for N in (20, 50) * 3:
            if verbose:
                print("Trying", N, "threads ...", end=' ')
            # Make sure that random and modulefinder get reimported freshly
            for modname in ['random', 'modulefinder']:
                try:
                    del sys.modules[modname]
                except KeyError:
                    pass
            errors = []
            done_tasks = []
            done.clear()
            for i in range(N):
                t = threading.Thread(target=task,
                                     args=(N, done, done_tasks, errors,))
                t.start()
            self.assertTrue(done.wait(60))
            self.assertFalse(errors)
            if verbose:
                print("OK.")
Example #23
0
    def post_process(self):
        try:
            # set file name
            if self.output == '':
                self.output = self.input[0:-len(self.input.split('.')[-1]) -
                                         1] + '_out.' + self.input.split(
                                             '.')[-1]
            # open file for output
            output_file = io.open(self.output,
                                  'w',
                                  encoding=self.writeEncoding)
            # write post-processed code to file
            output_file.write(self.__outputBuffer)
        finally:
            output_file.close()

        if self.run:
            # if this module is loaded as a library override the import
            if imp.lock_held() is True:
                self.override_import()
            else:
                self.on_the_fly()
        if not self.save:
            # remove tmp file
            if os.path.exists(self.output):
                os.remove(self.output)
        if not self.resume:
            # break execution so python doesn't
            # run the rest of the pre-processed code
            sys.exit(0)
Example #24
0
    def testLock(self):
        LOOPS = 50

        # The import lock may already be held, e.g. if the test suite is run
        # via "import test.autotest".
        lock_held_at_start = imp.lock_held()
        self.verify_lock_state(lock_held_at_start)

        for i in range(LOOPS):
            imp.acquire_lock()
            self.verify_lock_state(True)

        for i in range(LOOPS):
            imp.release_lock()

        # The original state should be restored now.
        self.verify_lock_state(lock_held_at_start)

        if not lock_held_at_start:
            try:
                imp.release_lock()
            except RuntimeError:
                pass
            else:
                self.fail("release_lock() without lock should raise "
                            "RuntimeError")
Example #25
0
        def g(*a, **kw):
            enqueued = curtime()
            ctx = context.get_context()
            started = []

            def in_thread(*a, **kw):
                ml.ld3("In thread {0}", f.__name__)
                started.append(curtime())
                return f(*a, **kw)

            # some modules import things lazily; it is too dangerous
            # to run a function in another thread if the import lock is
            # held by the current thread (this happens rarely -- only
            # if the thread dispatched function is being executed at
            # the import time of a module)
            if not ctx.cpu_thread_enabled or imp.lock_held():
                ret = in_thread(*a, **kw)
            elif in_threadpool() is self.pool:
                ret = in_thread(*a, **kw)
            else:
                ctx.stats[self.name + '.depth'].add(1 + len(self.pool))
                ret = self.pool.apply_e((Exception,), in_thread, a, kw)
                ml.ld3("Enqueued to thread {0}/depth {1}", f.__name__, len(pool))
            start = started[0]
            duration = curtime() - start
            queued = start - enqueued
            if hasattr(ret, '__len__') and callable(ret.__len__):
                prsize = ret.__len__()  # parameter-or-return size
            elif a and hasattr(a[0], '__len__') and callable(a[0].__len__):
                prsize = a[0].__len__()
            else:
                prsize = None
            _queue_stats(name, f.__name__, queued, duration, prsize)
            return ret
Example #26
0
        def __enter__(self):
            if self.sync or imp.lock_held():
                # Some modules like nosetests, coverage etc
                #   python -m unittest test_xxx.py  or  nosetests test_xxx.py
                # hang when Python multi-threading was used in the import stage due to (Python
                # import lock) bug in the threading module.  See also
                # https://github.com/paramiko/paramiko/issues/104
                # https://docs.python.org/2/library/threading.html#importing-in-threaded-code
                # Disable the asynchoronous mode for safe importing
                def def_async_fn(fn):
                    return fn

            else:
                # Enable back-ground mode
                def def_async_fn(fn):
                    def async_fn(*args, **kwargs):
                        if self.handler is not None:
                            self.handler.join()
                        self.handler = ThreadWithTraceBack(target=fn,
                                                           args=args,
                                                           kwargs=kwargs)
                        self.handler.start()
                        return self.handler

                    return async_fn

            if len(self.fns) == 1:
                return def_async_fn(self.fns[0])
            else:
                return [def_async_fn(fn) for fn in self.fns]
    def check_parallel_module_init(self):
        if imp.lock_held():
            # This triggers on, e.g., from test import autotest.
            raise unittest.SkipTest("can't run when import lock is held")

        done = threading.Event()
        for N in (20, 50) * 3:
            if verbose:
                print("Trying", N, "threads ...", end=' ')
            # Make sure that random and modulefinder get reimported freshly
            for modname in ['random', 'modulefinder']:
                try:
                    del sys.modules[modname]
                except KeyError:
                    pass
            errors = []
            done_tasks = []
            done.clear()
            for i in range(N):
                thread.start_new_thread(task, (
                    N,
                    done,
                    done_tasks,
                    errors,
                ))
            done.wait(60)
            self.assertFalse(errors)
            if verbose:
                print("OK.")
Example #28
0
    def blocking(fullname, requested_type):

        if utils.is_reactor_thread():
            try:
                raise ImportError(
                    "Cannot import %s: Remote import from reactor thread." %
                    fullname)
            except:
                logger.exception(
                    "Cannot import %s: Remote import from reactor thread." %
                    fullname)
                raise

        def in_reactor():
            d = receiver(fullname, requested_type)
            return d

        try:
            release_count = 0
            while imp.lock_held():
                release_count += 1
                imp.release_lock()

            return threads.blockingCallFromThread(reactor, in_reactor)
        finally:

            while release_count:
                release_count -= 1
                imp.acquire_lock()
Example #29
0
 def post_process(self):
     if self.input == self.output and self.__inputBuffer == self.__outputBuffer:
         return
     try:
         # open file for output (no auto-run)
         if self.output != "":
             self.run = False
             output_file = open(self.output, "w")
         # open tmp file
         else:
             self.run = True
             self.output = "tmp_" + os.path.basename(self.input)
             output_file = open(self.output, "w")
         # write post-processed code to file
         output_file.write(self.__outputBuffer)
     finally:
         output_file.close()
     # resolve postprocess stage depending on the mode
     if self.run == False:
         return
     else:
         # if this module is loaded as a library override the import
         if imp.lock_held() is True:
             self.override_import()
         else:
             self.on_the_fly()
             # break execution so python doesn't
             # run the rest of the pre-processed code
             return
Example #30
0
    def load_module(self, module_name):
        thread_count = threading.active_count()
        if thread_count != 1 :
            while imp.lock_held():
                pass
            imp.acquire_lock()

        module = sys.modules.setdefault(module_name, imp.new_module(module_name))

        if thread_count != 1:
            imp.release_lock() # not sure when to release; the following doesn't use shared resources (e.g. sys.modules) other than the module itself

        source, filepath = self.source.pop(module_name)
        module_code = compile(source, module_name, "exec")
        is_package = True if len(module_name.split('.')) > 1 else False # not sure, but seems accurate
        module.__file__ = filepath
        module.__loader__ = self
        if is_package:
            module.__path__ = []
            module.__package__ = module_name
        else:
            module.__package__ = module_name.split('.', 1)[0]
        exec module_code in module.__dict__
        #imp.release_lock() # it might be more correct to release the lock here instead of above.
        return module
Example #31
0
        def view_import(name, globals={}, locals={}, fromlist=[], level=0):
            """the drop-in replacement for __import__, that optionally imports
            locally as well.
            """
            # don't override nested imports
            save_import = builtin_mod.__import__
            builtin_mod.__import__ = local_import

            if imp.lock_held():
                # this is a side-effect import, don't do it remotely, or even
                # ignore the local effects
                return local_import(name, globals, locals, fromlist, level)

            imp.acquire_lock()
            if local:
                mod = local_import(name, globals, locals, fromlist, level)
            else:
                raise NotImplementedError("remote-only imports not yet implemented")
            imp.release_lock()

            key = name+':'+','.join(fromlist or [])
            if level <= 0 and key not in modules:
                modules.add(key)
                if not quiet:
                    if fromlist:
                        print("importing %s from %s on engine(s)"%(','.join(fromlist), name))
                    else:
                        print("importing %s on engine(s)"%name)
                results.append(self.apply_async(remote_import, name, fromlist, level))
            # restore override
            builtin_mod.__import__ = save_import

            return mod
Example #32
0
 def other_thread():
     imp.acquire_lock()        # 3
     assert imp.lock_held()
     lock_held.release()       # 4
     test_complete.acquire()   # 7
     imp.release_lock()        # 8
     lock_released.release()   # 9
Example #33
0
    def wait(self):
        """
        If this isn't the master process, wait for instructions.

        """
        if self.is_master():
            return

        status = MPI.Status()

        while True:
            # Event loop.
            # Sit here and await instructions.
            if self.debug:
                print("Worker {0} waiting for task.".format(self.rank))

            # Blocking receive to wait for instructions.
            task = self.comm.bcast(None)
            if self.debug:
                print("Worker {0} got task {1}.".format(self.rank, task))

            # Check if message is special sentinel signaling end.
            # If so, stop.
            if isinstance(task, _close_pool_message):
                if self.debug:
                    print("Worker {0} close.".format(self.rank))


# Handle global import lock for multithreading, see
#   http://stackoverflow.com/questions/12389526/import-inside-of-a-python-thread
#   https://docs.python.org/3.4/library/imp.html#imp.lock_held
# Global import lock affects the ctypes module.  It leads to deadlock when
# ctypes function is called in new threads created by threading module.
                if sys.version_info < (3, 4):
                    if not imp.lock_held():
                        imp.acquire_lock()
                return

            # Check if message is special type containing new function
            # to be applied
            elif isinstance(task, _function_wrapper):
                code = marshal.loads(task.func_code)

                if self.debug:
                    print('function {0}'.format(code))
                    print("Worker {0} replaced its task function: {1}.".format(
                        self.rank, self.function))
                self.function = types.FunctionType(code, globals())

            else:  # message are function args
                self.worker_status = 'R'
                ans = self.function(*task)  # task = worker_args
                if isinstance(ans, types.GeneratorType):
                    print(
                        '\nWARNING\n  Function {0} returns generator {1}.\n'
                        '  The generator was consumed to avoid workers getting stuck.\n'
                        .format(self.function, ans))
                    [x for x in ans]
                ans = x = None
                self.worker_status = 'P'
Example #34
0
 def test_lock(self):
     i=0
     while i<5:
         i+=1
         if not imp.lock_held():
             self.assertRaises(RuntimeError,imp.release_lock)
             imp.acquire_lock()
         else:
             imp.release_lock()
Example #35
0
 def CreateRPC(self):
     """ Create an RPC that can be used asynchronously. """
     # If the runtime is importing a module, fall back to the non-threaded RPC.
     # This prevents a deadlock in cases when the RealRPC thread tries to
     # acquire the import lock.
     if imp.lock_held():
         return apiproxy_rpc.RPC(stub=self)
     else:
         return apiproxy_rpc.RealRPC(stub=self)
Example #36
0
 def CreateRPC(self):
   """ Create an RPC that can be used asynchronously. """
   # If the runtime is importing a module, fall back to the non-threaded RPC.
   # This prevents a deadlock in cases when the RealRPC thread tries to
   # acquire the import lock.
   if imp.lock_held():
     return apiproxy_rpc.RPC(stub=self)
   else:
     return apiproxy_rpc.RealRPC(stub=self)
Example #37
0
def test_lock():
    i=0
    while i<5:
        i+=1
        if not imp.lock_held():
            AssertError(RuntimeError,imp.release_lock)
            imp.acquire_lock()
        else:
            imp.release_lock()
Example #38
0
 def test_lock(self):
     i=0
     while i<5:
         i+=1
         if not imp.lock_held():
             self.assertRaises(RuntimeError,imp.release_lock)
             imp.acquire_lock()
         else:
             imp.release_lock()
Example #39
0
def test_lock():
    i=0
    while i<5:
        i+=1
        if not imp.lock_held():
            AssertError(RuntimeError,imp.release_lock)
            imp.acquire_lock()
        else:
            imp.release_lock()
Example #40
0
    def wait(self):
        """
        If this isn't the master process, wait for instructions.

        """
        if self.is_master():
            return

        status = MPI.Status()

        while True:
            # Event loop.
            # Sit here and await instructions.
            if self.debug:
                print("Worker {0} waiting for task.".format(self.rank))

            # Blocking receive to wait for instructions.
            task = self.comm.bcast(None)
            if self.debug:
                print("Worker {0} got task {1}.".format(self.rank, task))

            # Check if message is special sentinel signaling end.
            # If so, stop.
            if isinstance(task, _close_pool_message):
                if self.debug:
                    print("Worker {0} close.".format(self.rank))
# Handle global import lock for multithreading, see
#   http://stackoverflow.com/questions/12389526/import-inside-of-a-python-thread
#   https://docs.python.org/3.4/library/imp.html#imp.lock_held
# Global import lock affects the ctypes module.  It leads to deadlock when
# ctypes function is called in new threads created by threading module.
                if sys.version_info < (3,4):
                    if not imp.lock_held():
                        imp.acquire_lock()
                return

            # Check if message is special type containing new function
            # to be applied
            elif isinstance(task, _function_wrapper):
                code = marshal.loads(task.func_code)
                if self.debug:
                    print('function {0}'.format(code))
                    print("Worker {0} replaced its task function: {1}."
                          .format(self.rank, self.function))
                self.function = types.FunctionType(code, globals())

            else:  # message are function args
                self.worker_status = 'R'
                ans = self.function(*task)  # task = worker_args
                if isinstance(ans, types.GeneratorType):
                    print('\nWARNING\n  Function {0} returns generator {1}.\n'
                          '  The generator was consumed to avoid workers getting stuck.\n'
                          .format(self.function, ans))
                    [x for x in ans]
                ans = x = None
                self.worker_status = 'P'
Example #41
0
        def __enter__(self):
            fns = self.fns
            handlers = self.handlers
            ntasks = len(self.fns)

            global_import_lock = False
            if sys.version_info < (3, 6):
                import imp
                global_import_lock = imp.lock_held()

            if self.sync or global_import_lock:
                # Some modules like nosetests, coverage etc
                #   python -m unittest test_xxx.py  or  nosetests test_xxx.py
                # hang when Python multi-threading was used in the import stage due to (Python
                # import lock) bug in the threading module.  See also
                # https://github.com/paramiko/paramiko/issues/104
                # https://docs.python.org/2/library/threading.html#importing-in-threaded-code
                # Disable the asynchoronous mode for safe importing
                def def_async_fn(i):
                    return fns[i]

            elif ThreadPoolExecutor is None:  # async mode, old python

                def def_async_fn(i):
                    def async_fn(*args, **kwargs):
                        if self.handlers[i] is not None:
                            self.handlers[i].join()
                        self.handlers[i] = ThreadWithTraceBack(target=fns[i],
                                                               args=args,
                                                               kwargs=kwargs)
                        self.handlers[i].start()
                        return self.handlers[i]

                    return async_fn

            else:  # multiple executors in async mode, python 2.7.12 or newer
                executor = self.executor = ThreadPoolExecutor(
                    max_workers=ntasks)

                def def_async_fn(i):
                    def async_fn(*args, **kwargs):
                        if handlers[i] is not None:
                            try:
                                handlers[i].result()
                            except Exception as e:
                                raise ThreadRuntimeError(
                                    'Error on thread %s:\n%s' % (self, e))
                        handlers[i] = executor.submit(fns[i], *args, **kwargs)
                        return handlers[i]

                    return async_fn

            if len(self.fns) == 1:
                return def_async_fn(0)
            else:
                return [def_async_fn(i) for i in range(ntasks)]
Example #42
0
    def test_waiting_during_different_thread_importing(self):
        """
        EventualResult.wait() should work if called while a module is
        being imported in a different thread. See
        EventualResultTests.test_noWaitingDuringImport for the explanation of
        what should happen if an import is happening in the current thread.
        """
        test_complete = threading.Event()
        lock_held = threading.Event()
        er = EventualResult(succeed(123), None)

        def other_thread():
            imp.acquire_lock()
            lock_held.set()
            test_complete.wait()
            imp.release_lock()

        t = threading.Thread(target=other_thread)
        t.start()
        lock_held.wait()

        # While the imp lock is held by the other thread, we can't
        # allow exceptions/assertions to happen because trial will
        # try to do an import causing a deadlock instead of a
        # failure. We collect all assertion pairs (result, expected),
        # wait for the import lock to be released, and then check our
        # assertions at the end of the test.
        assertions = []

        # we want to run .wait while the other thread has the lock acquired
        assertions.append((imp.lock_held(), True))
        try:
            assertions.append((er.wait(), 123))
        finally:
            test_complete.set()

        assertions.append((imp.lock_held(), True))

        test_complete.set()

        t.join()

        [self.assertEqual(result, expected) for result, expected in assertions]
Example #43
0
    def test_waiting_during_different_thread_importing(self):
        """
        EventualResult.wait() should work if called while a module is
        being imported in a different thread. See
        EventualResultTests.test_noWaitingDuringImport for the explanation of
        what should happen if an import is happening in the current thread.
        """
        test_complete = threading.Event()
        lock_held = threading.Event()
        er = EventualResult(succeed(123), None)

        def other_thread():
            imp.acquire_lock()
            lock_held.set()
            test_complete.wait()
            imp.release_lock()

        t = threading.Thread(target=other_thread)
        t.start()
        lock_held.wait()

        # While the imp lock is held by the other thread, we can't
        # allow exceptions/assertions to happen because trial will
        # try to do an import causing a deadlock instead of a
        # failure. We collect all assertion pairs (result, expected),
        # wait for the import lock to be released, and then check our
        # assertions at the end of the test.
        assertions = []

        # we want to run .wait while the other thread has the lock acquired
        assertions.append((imp.lock_held(), True))
        try:
            assertions.append((er.wait(), 123))
        finally:
            test_complete.set()

        assertions.append((imp.lock_held(), True))

        test_complete.set()

        t.join()

        [self.assertEqual(result, expected) for result, expected in assertions]
Example #44
0
 def g(*a, **kw):
     ctx = context.get_context()
     # in_cpubound_thread is sentinel to prevent double-thread dispatch
     if (not ctx.cpu_thread_enabled or imp.lock_held()
             or getattr(ctx.thread_locals, 'in_cpubound_thread', False)):
         return f(*a, **kw)
     if not hasattr(ctx.thread_locals, 'cpu_bound_thread'):
         ctx.thread_locals.cpu_bound_thread = CPUThread()
     ml.ld3("Calling in cpu thread {0}", f.__name__)
     return ctx.thread_locals.cpu_bound_thread.apply(f, a, kw)
def test_main():
    import imp
    if imp.lock_held():
        # If the import lock is held, the threads will hang.
        raise TestSkipped("can't run when import lock is held")

    try:
        testall()
    finally:
        cleanup()
Example #46
0
def test_main():
    import imp
    if imp.lock_held():
        # If the import lock is held, the threads will hang.
        raise TestSkipped("can't run when import lock is held")

    try:
        testall()
    finally:
        cleanup()
Example #47
0
 def find_module(self, name, path=None):
     # Simulate some thread-unsafe behaviour. If calls to find_module()
     # are properly serialized, `x` will end up the same as `numcalls`.
     # Otherwise not.
     assert imp.lock_held()
     with self.lock:
         self.numcalls += 1
     x = self.x
     time.sleep(0.01)
     self.x = x + 1
Example #48
0
 def find_module(self, name, path=None):
     # Simulate some thread-unsafe behaviour. If calls to find_module()
     # are properly serialized, `x` will end up the same as `numcalls`.
     # Otherwise not.
     assert imp.lock_held()
     with self.lock:
         self.numcalls += 1
     x = self.x
     time.sleep(0.01)
     self.x = x + 1
Example #49
0
 def g(*a, **kw):
     ctx = context.get_context()
     # in_cpubound_thread is sentinel to prevent double-thread dispatch
     if (not ctx.cpu_thread_enabled or imp.lock_held()
             or getattr(ctx.thread_locals, 'in_cpubound_thread', False)):
         return f(*a, **kw)
     if not hasattr(ctx.thread_locals, 'cpu_bound_thread'):
         ctx.thread_locals.cpu_bound_thread = CPUThread()
     ml.ld3("Calling in cpu thread {0}", f.__name__)
     return ctx.thread_locals.cpu_bound_thread.apply(f, a, kw)
Example #50
0
 def test_import_lock(self):
     import thread, imp
     assert not imp.lock_held()
     done = []
     def f():
         print '[ENTER %d]' % i
         from imghdr import testall
         print '[LEAVE %d]' % i
         done.append(1)
     for i in range(5):
         print '[RUN %d]' % i
         thread.start_new_thread(f, ())
     self.waitfor(lambda: len(done) == 5)
     assert len(done) == 5
Example #51
0
    def test_import_lock(self):
        import thread, imp
        assert not imp.lock_held()
        done = []

        def f():
            print '[ENTER %d]' % i
            from imghdr import testall
            print '[LEAVE %d]' % i
            done.append(1)

        for i in range(5):
            print '[RUN %d]' % i
            thread.start_new_thread(f, ())
        self.waitfor(lambda: len(done) == 5)
        assert len(done) == 5
Example #52
0
 def test_import_lock(self):
     # XXX XXX XXX this test fails if run together with all other tests
     # of this directory, but not when run alone
     import thread, imp
     assert not imp.lock_held()
     done = []
     def f(i):
         print '[ENTER %d]' % i
         from imghdr import testall
         print '[LEAVE %d]' % i
         done.append(1)
     for i in range(5):
         print '[RUN %d]' % i
         thread.start_new_thread(f, (i,))
     self.waitfor(lambda: len(done) == 5)
     assert len(done) == 5
Example #53
0
 def test_import_lock(self):
     # XXX XXX XXX this test fails if run together with all other tests
     # of this directory, but not when run alone
     import _thread, imp
     assert not imp.lock_held()
     done = []
     def f(i):
         print('[ENTER %d]' % i)
         from imghdr import testall
         print('[LEAVE %d]' % i)
         done.append(1)
     for i in range(5):
         print('[RUN %d]' % i)
         _thread.start_new_thread(f, (i,))
     self.waitfor(lambda: len(done) == 5)
     assert len(done) == 5
def test_main():        # magic name!  see above
    global N, done

    import imp
    if imp.lock_held():
        # This triggers on, e.g., from test import autotest.
        raise TestSkipped("can't run when import lock is held")

    done.acquire()
    for N in (20, 50) * 3:
        if verbose:
            print "Trying", N, "threads ...",
        for i in range(N):
            thread.start_new_thread(task, ())
        done.acquire()
        if verbose:
            print "OK."
Example #55
0
def execute(meth,*args, **kwargs):
    """
    Execute *meth* in a Python thread, blocking the current coroutine/
    greenthread until the method completes.

    The primary use case for this is to wrap an object or module that is not
    amenable to monkeypatching or any of the other tricks that Eventlet uses
    to achieve cooperative yielding.  With tpool, you can force such objects to
    cooperate with green threads by sticking them in native threads, at the cost
    of some overhead.
    """
    setup()
    # if already in tpool, don't recurse into the tpool
    # also, call functions directly if we're inside an import lock, because
    # if meth does any importing (sadly common), it will hang
    my_thread = threading.currentThread()
    if my_thread in _threads or imp.lock_held() or _nthreads == 0:
        return meth(*args, **kwargs)

    cur = greenthread.getcurrent()
    # a mini mixing function to make up for the fact that hash(greenlet) doesn't
    # have much variability in the lower bits
    k = hash(cur)
    k = k + 0x2c865fd + (k >> 5)
    k = k ^ 0xc84d1b7 ^ (k >> 7)
    thread_index = k % _nthreads
    
    reqq, _thread = _threads[thread_index]
    e = event.Event()
    reqq.put((e,meth,args,kwargs))

    rv = e.wait()
    if isinstance(rv,tuple) \
      and len(rv) == 3 \
      and isinstance(rv[1],EXC_CLASSES):
        import traceback
        (c,e,tb) = rv
        if not QUIET:
            traceback.print_exception(c,e,tb)
            traceback.print_stack()
        raise c,e,tb
    return rv
Example #56
0
 def test_lock_held_by_another_thread(self):
     import thread, imp
     lock_held = thread.allocate_lock()
     test_complete = thread.allocate_lock()
     lock_released = thread.allocate_lock()
     def other_thread():
         imp.acquire_lock()        # 3
         assert imp.lock_held()
         lock_held.release()       # 4
         test_complete.acquire()   # 7
         imp.release_lock()        # 8
         lock_released.release()   # 9
     lock_held.acquire()
     test_complete.acquire()
     lock_released.acquire()
     #
     thread.start_new_thread(other_thread, ())  # 1
     lock_held.acquire()                        # 2
     assert imp.lock_held()                     # 5
     test_complete.release()                    # 6
     lock_released.acquire()                    # 10
Example #57
0
    def apply(self, library_name, inputhash, dry_run = False):
        """
        Changes the state of the system according to what the module
        specified does

        Keyword arguments:
            library_name -- the python module to load
            inputhash -- the list of dictionaries of config for the library
            dry_run -- whether or not to actually change the system
        """
        log.debug('entering state.apply %s', [library_name, inputhash, dry_run])
        if library_name not in sys.modules:
            try:
                imp.acquire_lock()
                mod = imp.find_module(library_name, self.libraries)
                imp.load_module(library_name, *mod)
            except ImportError:
                log.exception("Couldn't find module %s in dirs %s", library_name, self.libraries)
                raise
            finally:
                if imp.lock_held():
                    imp.release_lock()
        log.debug('loading library: %s', library_name)
        library = importlib.import_module(library_name)
        schema = library.schema()

        for item in inputhash:
            jsonschema.validate(item, schema)

        failed = library.verify(inputhashes=inputhash, log=log)
        log.debug('dry run: %s', dry_run) 
        if not dry_run:
            log.debug('applying state...')
            library.apply(inputhashes=failed, log=log)
            failed = library.verify(inputhashes=inputhash, log=log)
            if len(failed) > 0:
                log.error("Failed for good on {}".format(failed))
        log.debug('Leaving state.apply %s', failed)
        return failed
Example #58
0
        try:
            module = imp.load_module(segment, module_file, module_path, module_description)
            path = getattr(module, '__path__', None)
        except SyntaxError, e:
            raise
        except ImportError,e:
            raise
        except Exception, e:
            if not silent:
                raise
            module = None
            error = e
        finally:
            if module_file:
                module_file.close()
            if imp.lock_held():
                imp.release_lock()
    return module
    
class GnrException(Exception):
    """Standard Gnr Exception"""
    code = 'GNR-001'
    description = '!!Genro base exception'
    caption = """!!Error code %(code)s : %(description)s."""
    localizer = None
    
    def __init__(self, description=None, **kwargs):
        if description:
            self.description = description
        self.msgargs = kwargs
        self.localizer = None
Example #59
0
 def verify_lock_state(self, expected):
     self.assertEqual(imp.lock_held(), expected,
                          "expected imp.lock_held() to be %r" % expected)