File: monitor.rb

package info (click to toggle)
ruby-nio4r 2.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 608 kB
  • sloc: ansic: 7,611; java: 700; ruby: 364; makefile: 7
file content (124 lines) | stat: -rw-r--r-- 3,342 bytes parent folder | download | duplicates (2)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2011-2018, by Tony Arcieri.
# Copyright, 2015, by Upekshe Jayasekera.
# Copyright, 2015, by Vladimir Kochnev.
# Copyright, 2018-2023, by Samuel Williams.
# Copyright, 2019-2020, by Gregory Longtin.

module NIO
  # Monitors watch IO objects for specific events
  class Monitor
    attr_reader :io, :interests, :selector
    attr_accessor :value, :readiness

    # :nodoc:
    def initialize(io, interests, selector)
      unless defined?(::OpenSSL) && io.is_a?(::OpenSSL::SSL::SSLSocket)
        unless io.is_a?(IO)
          if IO.respond_to? :try_convert
            io = IO.try_convert(io)
          elsif io.respond_to? :to_io
            io = io.to_io
          end

          raise TypeError, "can't convert #{io.class} into IO" unless io.is_a? IO
        end
      end

      @io        = io
      @interests = interests
      @selector  = selector
      @closed    = false
    end

    # Replace the existing interest set with a new one
    #
    # @param interests [:r, :w, :rw, nil] I/O readiness we're interested in (read/write/readwrite)
    #
    # @return [Symbol] new interests
    def interests=(interests)
      raise EOFError, "monitor is closed" if closed?
      raise ArgumentError, "bad interests: #{interests}" unless [:r, :w, :rw, nil].include?(interests)

      @interests = interests
    end

    # Add new interests to the existing interest set
    #
    # @param interests [:r, :w, :rw] new I/O interests (read/write/readwrite)
    #
    # @return [self]
    def add_interest(interest)
      case interest
      when :r
        case @interests
        when :r  then @interests = :r
        when :w  then @interests = :rw
        when :rw then @interests = :rw
        when nil then @interests = :r
        end
      when :w
        case @interests
        when :r  then @interests = :rw
        when :w  then @interests = :w
        when :rw then @interests = :rw
        when nil then @interests = :w
        end
      when :rw
        @interests = :rw
      else raise ArgumentError, "bad interests: #{interest}"
      end
    end

    # Remove interests from the existing interest set
    #
    # @param interests [:r, :w, :rw] I/O interests to remove (read/write/readwrite)
    #
    # @return [self]
    def remove_interest(interest)
      case interest
      when :r
        case @interests
        when :r  then @interests = nil
        when :w  then @interests = :w
        when :rw then @interests = :w
        when nil then @interests = nil
        end
      when :w
        case @interests
        when :r  then @interests = :r
        when :w  then @interests = nil
        when :rw then @interests = :r
        when nil then @interests = nil
        end
      when :rw
        @interests = nil
      else raise ArgumentError, "bad interests: #{interest}"
      end
    end

    # Is the IO object readable?
    def readable?
      readiness == :r || readiness == :rw
    end

    # Is the IO object writable?
    def writable?
      readiness == :w || readiness == :rw
    end
    alias writeable? writable?

    # Is this monitor closed?
    def closed?
      @closed
    end

    # Deactivate this monitor
    def close(deregister = true)
      @closed = true
      @selector.deregister(io) if deregister
    end
  end
end