This file is indexed.

/usr/lib/ruby/vendor_ruby/em-hiredis/lock.rb is in ruby-em-hiredis 0.3.0-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
require 'securerandom'

module EM::Hiredis
  # Cross-process re-entrant lock, backed by redis
  class Lock

    EM::Hiredis::Client.load_scripts_from(File.expand_path("../lock_lua", __FILE__))

    # Register a callback which will be called 1s before the lock expires
    # This is an informational callback, there is no hard guarantee on the timing
    # of its invocation because the callback firing and lock key expiry are handled
    # by different clocks (the client process and redis server respectively)
    def onexpire(&blk); @onexpire = blk; end

    def initialize(redis, key, timeout)
      unless timeout.kind_of?(Fixnum) && timeout >= 1
        raise "Timeout must be an integer and >= 1s"
      end
      @redis, @key, @timeout = redis, key, timeout
      @token = SecureRandom.hex
    end

    # Acquire the lock
    #
    # This is a re-entrant lock, re-acquiring will succeed and extend the timeout
    #
    # Returns a deferrable which either succeeds if the lock can be acquired, or fails if it cannot.
    def acquire
      df = EM::DefaultDeferrable.new
      @redis.lock_acquire([@key], [@token, @timeout]).callback { |success|
        if (success)
          EM::Hiredis.logger.debug "#{to_s} acquired"

          EM.cancel_timer(@expire_timer) if @expire_timer
          @expire_timer = EM.add_timer(@timeout - 1) {
            EM::Hiredis.logger.debug "#{to_s} Expires in 1s"
            @onexpire.call if @onexpire
          }

          df.succeed
        else
          EM::Hiredis.logger.debug "#{to_s} failed to acquire"
          df.fail("Lock is not available")
        end
      }.errback { |e|
        EM::Hiredis.logger.error "#{to_s} Error acquiring lock #{e}"
        df.fail(e)
      }
      df
    end

    # Release the lock
    #
    # Returns a deferrable
    def unlock
      EM.cancel_timer(@expire_timer) if @expire_timer

      df = EM::DefaultDeferrable.new
      @redis.lock_release([@key], [@token]).callback { |keys_removed|
        if keys_removed > 0
          EM::Hiredis.logger.debug "#{to_s} released"
          df.succeed
        else
          EM::Hiredis.logger.debug "#{to_s} could not release, not held"
          df.fail("Cannot release a lock we do not hold")
        end
      }.errback { |e|
        EM::Hiredis.logger.error "#{to_s} Error releasing lock #{e}"
        df.fail(e)
      }
      df
    end

    # This should not be used in normal operation.
    # Force clear without regard to who owns the lock.
    def clear
      EM::Hiredis.logger.warn "#{to_s} Force clearing lock (unsafe)"
      EM.cancel_timer(@expire_timer) if @expire_timer

      @redis.del(@key)
    end

    def to_s
      "[lock #{@key}]"
    end

  end
end