def fetch(included_filename)
      if source = @cache[included_filename]
        return source
      end

      if @m.locked? && @owns_lock == Thread.current
        @cache[included_filename] = yield
      else
        ret = nil
        @cache[included_filename] = @m.synchronize do
          begin
            @owns_lock = Thread.current
            ret = yield
          ensure
            @owns_lock = nil
          end
        end
        ret
      end
    end
def fetch(included_filename)
      if source = @cache[included_filename]
        return source
      end

      if @m.locked? && @owns_lock == Thread.current
        @cache[included_filename] = yield
      else
        ret = nil
        @cache[included_filename] = @m.synchronize do
          begin
            @owns_lock = Thread.current
            ret = yield
          ensure
            @owns_lock = nil
          end
        end
        ret
      end
    end
`fetch` can be called recursively in the `yield`ed block, so must
 make sure not to try to lock the Mutex if it's already locked by the
 current thread, as this would result in an error.