<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def preserve_context(f):
 """ Package up the given function with the current Eliot context, and then restore context and call given function when the resulting callable is run. This allows continuing the action context within a different thread. The result should only be used once, since it relies on L{Action.serialize_task_id} whose results should only be deserialized once. @param f: A callable. @return: One-time use callable that calls given function in context of a child of current Eliot action. """

    action = current_action()
    if action is None:
        return f
    task_id = action.serialize_task_id()
    called = threading.Lock()

    def restore_eliot_context(*args, **kwargs):
        # Make sure the function has not already been called:
        if not called.acquire(False):
            raise TooManyCalls(f)

        with Action.continue_task(task_id=task_id):
            return f(*args, **kwargs)

    return restore_eliot_context