'Run the given method in a sub-thread with an existing stack lock.
Release the provided lock when the thread finishes.
:param stack: Stack to be operated on
:type stack: heat.engine.parser.Stack
:param lock: The acquired stack lock
:type lock: heat.engine.stack_lock.StackLock
:param func: Callable to be invoked in sub-thread
:type func: function or instancemethod
:param args: Args to be passed to func
:param kwargs: Keyword-args to be passed to func'

def start_with_acquired_lock(self, stack, lock, func, *args, **kwargs):

    def release(gt):
        'Callback    function    that    will    be    passed    to    GreenThread.link().\n\n                                                Persist    the    stack    state    to    COMPLETE    and    FAILED    close    to\n                                                releasing    the    lock    to    avoid    race    conditions.\n                                                '
        if ((stack is not None) and (stack.status != stack.IN_PROGRESS) and (stack.action not in (stack.DELETE, stack.ROLLBACK, stack.UPDATE))):
            stack.persist_state_and_release_lock(lock.engine_id)
        else:
            lock.release()
    stack.thread_group_mgr = self
    th = self.start(stack.id, func, *args, **kwargs)
    th.link(release)
    return th
