Class: Nl::Exchange
- Inherits:
-
Object
- Object
- Nl::Exchange
- Defined in:
- nl/lib/nl/exchange.rb
Overview
State machine for one Netlink request/reply exchange.
Dump exchanges are known to be multipart from the request and remain open through NLMSG_DONE. Some Linux Generic Netlink dump handlers construct replies with genlmsg_iput(), which leaves NLM_F_MULTI unset despite that multipart lifetime. Dump mode therefore accepts data with or without the flag; reply mode still uses it to detect a multipart do response.
Some operations also return multipart data for a do request, although YNL cannot declare such a reply. Reply mode handles this kernel behavior by retaining the first data message, draining the remainder, and completing on NLMSG_DONE instead of ACK.
Defined Under Namespace
Classes: Complete, Failure, Item
Constant Summary collapse
Instance Attribute Summary collapse
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
Instance Method Summary collapse
- #accept(frame) ⇒ Object
- #cancel ⇒ Object
- #cancelled? ⇒ Boolean
- #complete? ⇒ Boolean
-
#initialize(mode:) ⇒ Exchange
constructor
A new instance of Exchange.
- #result ⇒ Object
Constructor Details
#initialize(mode:) ⇒ Exchange
Returns a new instance of Exchange.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'nl/lib/nl/exchange.rb', line 29 def initialize(mode:) raise ArgumentError, "unknown exchange mode: #{mode.inspect}" unless MODES.include?(mode) @mode = mode @reply = nil # Receive states: # - :dump accepts and emits every data message, then completes on DONE. # - :no_reply rejects data and completes on ACK. # - :initial waits for the first data message of a reply operation. # - :single retains that message and completes once ACK is received. # - :multi retains the first message, drains the rest, and # completes on DONE. Every data message must carry NLM_F_MULTI. @state = mode == :reply ? :initial : mode @acked = false @cancelled = false @complete = false @result = nil @mutex = Mutex.new end |
Instance Attribute Details
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
26 27 28 |
# File 'nl/lib/nl/exchange.rb', line 26 def mode @mode end |
Instance Method Details
#accept(frame) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'nl/lib/nl/exchange.rb', line 49 def accept(frame) @mutex.synchronize do return if @complete case frame when Raw::UnknownFrame nil when Raw::ErrorFrame @cancelled ? complete(nil) : fail_with(SystemCallError.new(frame.errno)) when Raw::DoneFrame if frame.errno && !@cancelled fail_with(SystemCallError.new(frame.errno)) else complete(@reply) end when Raw::AckFrame accept_ack when Raw::DataFrame accept_reply(frame) else raise ArgumentError, "unexpected exchange input: #{frame.inspect}" end end end |
#cancel ⇒ Object
74 75 76 77 |
# File 'nl/lib/nl/exchange.rb', line 74 def cancel @mutex.synchronize { @cancelled = true unless @complete } nil end |
#cancelled? ⇒ Boolean
79 |
# File 'nl/lib/nl/exchange.rb', line 79 def cancelled? = @mutex.synchronize { @cancelled } |
#complete? ⇒ Boolean
80 |
# File 'nl/lib/nl/exchange.rb', line 80 def complete? = @mutex.synchronize { @complete } |
#result ⇒ Object
81 |
# File 'nl/lib/nl/exchange.rb', line 81 def result = @mutex.synchronize { @result } |