libvirt_ffi 0.2.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +78 -0
- data/Gemfile +7 -2
- data/Rakefile +6 -1
- data/bin/console +1 -0
- data/exe/libvirt +1 -0
- data/lib/libvirt.rb +14 -13
- data/lib/libvirt/base_info.rb +34 -0
- data/lib/libvirt/connection.rb +156 -47
- data/lib/libvirt/domain.rb +136 -8
- data/lib/libvirt/domain_callback_storage.rb +69 -0
- data/lib/libvirt/errors.rb +65 -0
- data/lib/libvirt/event.rb +60 -38
- data/lib/libvirt/ffi.rb +17 -0
- data/lib/libvirt/ffi/common.rb +8 -1
- data/lib/libvirt/ffi/domain.rb +796 -69
- data/lib/libvirt/ffi/error.rb +243 -0
- data/lib/libvirt/ffi/event.rb +30 -36
- data/lib/libvirt/ffi/helpers.rb +17 -0
- data/lib/libvirt/ffi/host.rb +122 -0
- data/lib/libvirt/ffi/storage.rb +149 -0
- data/lib/libvirt/ffi/stream.rb +74 -0
- data/lib/libvirt/node_info.rb +2 -41
- data/lib/libvirt/storage_pool.rb +70 -0
- data/lib/libvirt/storage_pool_info.rb +7 -0
- data/lib/libvirt/storage_volume.rb +51 -0
- data/lib/libvirt/storage_volume_info.rb +7 -0
- data/lib/libvirt/stream.rb +124 -0
- data/lib/libvirt/util.rb +75 -8
- data/lib/libvirt/version.rb +1 -1
- data/lib/libvirt/xml.rb +23 -0
- data/lib/libvirt/xml/disk.rb +59 -0
- data/lib/libvirt/xml/domain.rb +76 -0
- data/lib/libvirt/xml/generic.rb +252 -0
- data/lib/libvirt/xml/graphics.rb +14 -0
- data/lib/libvirt/xml/max_vcpu.rb +12 -0
- data/lib/libvirt/xml/memory.rb +14 -0
- data/lib/libvirt/xml/storage_pool.rb +24 -0
- data/lib/libvirt/xml/storage_volume.rb +32 -0
- data/lib/libvirt/xml/vcpu.rb +12 -0
- data/lib/libvirt_ffi.rb +2 -0
- data/libvirt.gemspec +5 -1
- data/test_usage/support/libvirt_async.rb +33 -31
- data/test_usage/support/log_formatter.rb +5 -10
- data/test_usage/test_domain.rb +43 -0
- data/test_usage/test_event_loop.rb +134 -33
- data/test_usage/test_libvirtd_restart.rb +63 -0
- data/test_usage/test_metadata.rb +104 -0
- data/test_usage/test_screenshot.rb +197 -0
- data/test_usage/test_storage.rb +52 -0
- metadata +46 -6
- data/lib/libvirt/error.rb +0 -6
- data/lib/libvirt/ffi/connection.rb +0 -84
- data/lib/libvirt/ffi/libvirt.rb +0 -17
- data/lib/libvirt/ffi/node_info.rb +0 -37
data/lib/libvirt/domain.rb
CHANGED
@@ -2,20 +2,35 @@
|
|
2
2
|
|
3
3
|
module Libvirt
|
4
4
|
class Domain
|
5
|
-
def
|
5
|
+
def self.load_ref(dom_ptr)
|
6
|
+
ref_result = FFI::Domain.virDomainRef(dom_ptr)
|
7
|
+
raise Errors::LibError, "Couldn't retrieve domain reference" if ref_result.negative?
|
8
|
+
|
9
|
+
new(dom_ptr)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(dom_ptr)
|
6
13
|
@dom_ptr = dom_ptr
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
14
|
+
|
15
|
+
free = ->(obj_id) do
|
16
|
+
Util.log(:debug) { "Finalize Libvirt::Domain 0x#{obj_id.to_s(16)} @dom_ptr=#{@dom_ptr}," }
|
17
|
+
return unless @dom_ptr
|
18
|
+
|
19
|
+
fr_result = FFI::Domain.virDomainFree(@dom_ptr)
|
20
|
+
warn "Couldn't free Libvirt::Domain (0x#{obj_id.to_s(16)}) pointer #{@dom_ptr.address}" if fr_result.negative?
|
21
|
+
end
|
22
|
+
ObjectSpace.define_finalizer(self, free)
|
11
23
|
end
|
12
24
|
|
13
25
|
def get_state
|
14
26
|
state = ::FFI::MemoryPointer.new(:int)
|
15
27
|
reason = ::FFI::MemoryPointer.new(:int)
|
16
28
|
result = FFI::Domain.virDomainGetState(@dom_ptr, state, reason, 0)
|
17
|
-
raise
|
18
|
-
|
29
|
+
raise Errors::LibError, "Couldn't get domain state" if result.negative?
|
30
|
+
|
31
|
+
state_sym = FFI::Domain.enum_type(:state)[state.read_int]
|
32
|
+
reason_sym = FFI::Domain.state_reason(state_sym, reason.read_int)
|
33
|
+
[state_sym, reason_sym]
|
19
34
|
end
|
20
35
|
|
21
36
|
def to_ptr
|
@@ -25,7 +40,8 @@ module Libvirt
|
|
25
40
|
def uuid
|
26
41
|
buff = ::FFI::MemoryPointer.new(:char, FFI::Domain::UUID_STRING_BUFLEN)
|
27
42
|
result = FFI::Domain.virDomainGetUUIDString(@dom_ptr, buff)
|
28
|
-
raise
|
43
|
+
raise Errors::LibError, "Couldn't get domain uuid" if result.negative?
|
44
|
+
|
29
45
|
buff.read_string
|
30
46
|
end
|
31
47
|
|
@@ -56,5 +72,117 @@ module Libvirt
|
|
56
72
|
def xml_desc(flags = 0)
|
57
73
|
FFI::Domain.virDomainGetXMLDesc(@dom_ptr, flags)
|
58
74
|
end
|
75
|
+
|
76
|
+
def screenshot(stream, display = 0)
|
77
|
+
dbg { "#screenshot stream=#{stream}, display=#{display}," }
|
78
|
+
|
79
|
+
mime_type, pointer = FFI::Domain.virDomainScreenshot(@dom_ptr, stream.to_ptr, display, 0)
|
80
|
+
raise Errors::LibError, "Couldn't attach domain screenshot" if pointer.null?
|
81
|
+
|
82
|
+
# free pointer required
|
83
|
+
mime_type
|
84
|
+
end
|
85
|
+
|
86
|
+
def free_domain
|
87
|
+
result = FFI::Domain.virDomainFree(@dom_ptr)
|
88
|
+
raise Errors::LibError, "Couldn't free domain" if result.negative?
|
89
|
+
|
90
|
+
@dom_ptr = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def start(flags = 0)
|
94
|
+
result = FFI::Domain.virDomainCreateWithFlags(@dom_ptr, flags)
|
95
|
+
raise Errors::LibError, "Couldn't start domain" if result.negative?
|
96
|
+
end
|
97
|
+
|
98
|
+
def reboot(flags = 0)
|
99
|
+
result = FFI::Domain.virDomainReboot(@dom_ptr, flags)
|
100
|
+
raise Errors::LibError, "Couldn't reboot domain" if result.negative?
|
101
|
+
end
|
102
|
+
|
103
|
+
def shutdown(flags = :ACPI_POWER_BTN)
|
104
|
+
result = FFI::Domain.virDomainShutdownFlags(@dom_ptr, flags)
|
105
|
+
raise Errors::LibError, "Couldn't shutdown domain" if result.negative?
|
106
|
+
end
|
107
|
+
|
108
|
+
def power_off(flags = 0)
|
109
|
+
result = FFI::Domain.virDomainDestroyFlags(@dom_ptr, flags)
|
110
|
+
raise Errors::LibError, "Couldn't power off domain" if result.negative?
|
111
|
+
end
|
112
|
+
|
113
|
+
def reset(flags = 0)
|
114
|
+
result = FFI::Domain.virDomainReset(@dom_ptr, flags)
|
115
|
+
raise Errors::LibError, "Couldn't reset domain" if result.negative?
|
116
|
+
end
|
117
|
+
|
118
|
+
def suspend
|
119
|
+
result = FFI::Domain.virDomainSuspend(@dom_ptr)
|
120
|
+
raise Errors::LibError, "Couldn't suspend domain" if result.negative?
|
121
|
+
end
|
122
|
+
|
123
|
+
def resume
|
124
|
+
result = FFI::Domain.virDomainResume(@dom_ptr)
|
125
|
+
raise Errors::LibError, "Couldn't resume domain" if result.negative?
|
126
|
+
end
|
127
|
+
|
128
|
+
# Undefine a domain.
|
129
|
+
# If the domain is running, it's converted to transient domain, without stopping it.
|
130
|
+
# If the domain is inactive, the domain configuration is removed.
|
131
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
132
|
+
# @see Libvirt::FFI::Domain enum :undefine_flags_values for acceptable keys
|
133
|
+
# @see Libvirt::Util.parse_flags for possible argument values
|
134
|
+
# @raise [Libvirt::Errors::LibError] if operation failed
|
135
|
+
def undefine(options_or_flags = nil)
|
136
|
+
flags = Util.parse_flags options_or_flags, FFI::Domain.enum_type(:undefine_flags_values)
|
137
|
+
result = FFI::Domain.virDomainUndefineFlags(@dom_ptr, flags)
|
138
|
+
raise Errors::LibError, "Couldn't resume domain" if result.negative?
|
139
|
+
end
|
140
|
+
|
141
|
+
# After save_memory(:PAUSED) you need to call #start and #resume
|
142
|
+
# to move domain to the running state.
|
143
|
+
def save_memory(flags = :PAUSED)
|
144
|
+
result = FFI::Domain.virDomainManagedSave(@dom_ptr, flags)
|
145
|
+
raise Errors::LibError, "Couldn't save domain memory" if result.negative?
|
146
|
+
end
|
147
|
+
|
148
|
+
# Sets metadata
|
149
|
+
# @param metadata [String] xml node for element type, text for other types
|
150
|
+
# DESCRIPTION 0x0 - Operate on <description>
|
151
|
+
# TITLE 0x1 - Operate on <title>
|
152
|
+
# ELEMENT 0x2 - Operate on <metadata>
|
153
|
+
# @param type [Integer,Symbol] one of :ELEMENT, :TITLE, :DESCRIPTION
|
154
|
+
# @param key [String] xml key (required for type element)
|
155
|
+
# @param uri [String] xml namespace (required for type element)
|
156
|
+
# @param flags [Integer,Symbol] one off AFFECT_CURRENT, AFFECT_CONFIG, AFFECT_LIVE
|
157
|
+
# AFFECT_CURRENT 0x0 - Affect current domain state.
|
158
|
+
# AFFECT_LIVE 0x1 - Affect running domain state.
|
159
|
+
# AFFECT_CONFIG 0x2 - Affect persistent domain state.
|
160
|
+
# @raise [Libvirt::Errors::LibError] if operation failed
|
161
|
+
def set_metadata(metadata, type: :ELEMENT, key: nil, uri: nil, flags: :AFFECT_CURRENT)
|
162
|
+
result = FFI::Domain.virDomainSetMetadata(@dom_ptr, type, metadata, key, uri, flags)
|
163
|
+
raise Errors::LibError, "Couldn't set domain metadata" if result.negative?
|
164
|
+
end
|
165
|
+
|
166
|
+
# Retrieves metadata
|
167
|
+
# @param type [Integer,Symbol] one of :ELEMENT, :TITLE, :DESCRIPTION
|
168
|
+
# @param uri [String] xml namespace (required for type element)
|
169
|
+
# @param flags [Integer,Symbol] one off AFFECT_CURRENT, AFFECT_CONFIG, AFFECT_LIVE
|
170
|
+
# AFFECT_CURRENT 0x0 - Affect current domain state.
|
171
|
+
# AFFECT_LIVE 0x1 - Affect running domain state.
|
172
|
+
# AFFECT_CONFIG 0x2 - Affect persistent domain state.
|
173
|
+
# @raise [Libvirt::Errors::LibError] if operation failed
|
174
|
+
# @return [String] xml node, title, or description.
|
175
|
+
def get_metadata(type: :ELEMENT, uri: nil, flags: :AFFECT_CURRENT)
|
176
|
+
result = FFI::Domain.virDomainGetMetadata(@dom_ptr, type, uri, flags)
|
177
|
+
raise Errors::LibError, "Couldn't get domain metadata" if result.nil?
|
178
|
+
|
179
|
+
result
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def dbg(&block)
|
185
|
+
Util.log(:debug, 'Libvirt::Domain', &block)
|
186
|
+
end
|
59
187
|
end
|
60
188
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
class DomainCallbackStorage
|
5
|
+
class CallbackDataStruct < ::FFI::Struct
|
6
|
+
layout :connection_pointer, :pointer,
|
7
|
+
:callback_id, :int
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@inner_storage = Hash.new { |h, key| h[key] = {} }
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Array<2>]
|
15
|
+
# cb_data [Libvirt::DomainCallbackStorage::CallbackDataStruct],
|
16
|
+
# cb_data_free_func [FFI::Function]
|
17
|
+
def allocate_struct
|
18
|
+
dbg { '#allocate_struct' }
|
19
|
+
|
20
|
+
cb_data_ptr = ::FFI::MemoryPointer.new(:char, CallbackDataStruct.size, false)
|
21
|
+
cb_data = CallbackDataStruct.new(cb_data_ptr)
|
22
|
+
cb_data_free_func = FFI::Common.free_function do |pointer|
|
23
|
+
dbg { 'Libvirt::DomainCallbackStorage cb_data_free_func triggered' }
|
24
|
+
remove_struct(pointer)
|
25
|
+
end
|
26
|
+
[cb_data, cb_data_free_func]
|
27
|
+
end
|
28
|
+
|
29
|
+
def store_struct(cb_data, connection_pointer:, callback_id:, cb:, opaque:)
|
30
|
+
dbg { '#store_struct' }
|
31
|
+
|
32
|
+
cb_data[:connection_pointer] = connection_pointer
|
33
|
+
cb_data[:callback_id] = callback_id
|
34
|
+
@inner_storage[connection_pointer.address][callback_id] = { cb: cb, opaque: opaque, pointer: cb_data.pointer }
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_struct(pointer)
|
38
|
+
dbg { "#remove_struct pointer=#{pointer}" }
|
39
|
+
|
40
|
+
cb_data_struct = CallbackDataStruct.new(pointer)
|
41
|
+
connection_pointer = cb_data_struct[:connection_pointer]
|
42
|
+
callback_id = cb_data_struct[:callback_id]
|
43
|
+
dbg { "#remove_struct pointer=#{pointer}, connection_pointer=#{connection_pointer}, callback_id=#{callback_id}," }
|
44
|
+
|
45
|
+
cb_data = @inner_storage[connection_pointer.address].delete(callback_id)
|
46
|
+
@inner_storage.delete(connection_pointer.address) if @inner_storage[connection_pointer.address].empty?
|
47
|
+
|
48
|
+
cb_data[:opaque]
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param [::FFI::Pointer]
|
52
|
+
# @return [Array<2>] cb [Proc], opaque [Object]
|
53
|
+
def retrieve_from_pointer(pointer)
|
54
|
+
dbg { "#retrieve_from_pointer pointer=#{pointer}," }
|
55
|
+
|
56
|
+
cb_data_struct = CallbackDataStruct.new(pointer)
|
57
|
+
connection_pointer = cb_data_struct[:connection_pointer]
|
58
|
+
callback_id = cb_data_struct[:callback_id]
|
59
|
+
cb_data = @inner_storage[connection_pointer.address][callback_id]
|
60
|
+
[cb_data[:cb], cb_data[:opaque]]
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def dbg(&block)
|
66
|
+
Util.log(:debug, 'Libvirt::DomainCallbackStorage', &block)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
module Errors
|
5
|
+
class Error < StandardError
|
6
|
+
# Generic error
|
7
|
+
end
|
8
|
+
|
9
|
+
class LibError < Error
|
10
|
+
# Object contains detailed error information retrieved from libvirt.
|
11
|
+
|
12
|
+
ERROR_FIELDS = [:code, :domain, :message, :level].freeze
|
13
|
+
|
14
|
+
attr_reader :client_message,
|
15
|
+
:error_data,
|
16
|
+
:error_code,
|
17
|
+
:error_domain,
|
18
|
+
:error_message,
|
19
|
+
:error_level
|
20
|
+
|
21
|
+
# @param client_message [String, nil] optional client message
|
22
|
+
# When client_message ommited and virGetLastError return error
|
23
|
+
# message will be following: "ERROR_LEVEL: ERROR_NUMBER (ERROR_DOMAIN) ERROR_MESSAGE".
|
24
|
+
# When client message provided and virGetLastError return error
|
25
|
+
# message will be following: "CLIENT_MESSAGE\nERROR_LEVEL: ERROR_NUMBER (ERROR_DOMAIN) ERROR_MESSAGE".
|
26
|
+
# When client message is provided and virGetLastError return no error
|
27
|
+
# message will be following: "CLIENT_MESSAGE".
|
28
|
+
def initialize(client_message = nil)
|
29
|
+
@client_message = client_message
|
30
|
+
ptr = FFI::Error.virGetLastError
|
31
|
+
unless ptr.null?
|
32
|
+
struct = FFI::Error::Struct.new(ptr)
|
33
|
+
@error_data = struct.members.map { |m| [m, struct[m]] }.to_h
|
34
|
+
@error_code = error_data[:code]
|
35
|
+
@error_domain = error_data[:domain]
|
36
|
+
@error_message = error_data[:message]
|
37
|
+
@error_level = error_data[:level]
|
38
|
+
end
|
39
|
+
|
40
|
+
super(build_message)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def build_message
|
46
|
+
if error_data.nil?
|
47
|
+
client_message
|
48
|
+
elsif client_message.nil?
|
49
|
+
format '%<level>s: %<code>s (%<domain>s) %<message>s',
|
50
|
+
level: error_level,
|
51
|
+
code: error_code,
|
52
|
+
domain: error_domain,
|
53
|
+
message: error_message
|
54
|
+
else
|
55
|
+
format "%<client_message>s\n%<level>s: %<code>s (%<domain>s) %<message>s",
|
56
|
+
client_message: client_message,
|
57
|
+
level: error_level,
|
58
|
+
code: error_code,
|
59
|
+
domain: error_domain,
|
60
|
+
message: error_message
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/libvirt/event.rb
CHANGED
@@ -9,24 +9,32 @@ module Libvirt
|
|
9
9
|
extend Forwardable
|
10
10
|
extend SingleForwardable
|
11
11
|
|
12
|
-
single_delegate [
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
single_delegate [
|
13
|
+
:register,
|
14
|
+
:unregister,
|
15
|
+
:registered?,
|
16
|
+
:debug,
|
17
|
+
:debug=,
|
18
|
+
:invoke_handle_callback,
|
19
|
+
:invoke_timeout_callback
|
20
|
+
] => :instance
|
21
|
+
|
22
|
+
attr_accessor :debug
|
23
|
+
|
24
|
+
Opaque = Struct.new(:cb, :opaque, :free_func)
|
25
|
+
|
26
|
+
def invoke_handle_callback(watch, fd, events, opaque)
|
27
|
+
cb = opaque.cb
|
28
|
+
op = opaque.opaque
|
29
|
+
dbg { "INVOKE_HANDLE_CALLBACK watch=#{watch} fd=#{fd} events=#{events} op=#{op}" }
|
30
|
+
cb.call(watch, fd, events, op)
|
31
|
+
end
|
23
32
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
33
|
+
def invoke_timeout_callback(timer, opaque)
|
34
|
+
cb = opaque.cb
|
35
|
+
op = opaque.opaque
|
36
|
+
dbg { "INVOKE_TIMEOUT_CALLBACK timer=#{timer} op=#{op}" }
|
37
|
+
cb.call(timer, op)
|
30
38
|
end
|
31
39
|
|
32
40
|
def registered?
|
@@ -51,20 +59,25 @@ module Libvirt
|
|
51
59
|
true
|
52
60
|
end
|
53
61
|
|
54
|
-
def
|
62
|
+
def schedule_operation(&block)
|
63
|
+
@schedule.call(&block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def register(add_handle:, update_handle:, remove_handle:, add_timer:, update_timer:, remove_timer:, schedule:) # rubocop:disable Metrics/ParameterLists
|
55
67
|
@add_handle = add_handle
|
56
68
|
@update_handle = update_handle
|
57
69
|
@remove_handle = remove_handle
|
58
70
|
@add_timer = add_timer
|
59
71
|
@update_timer = update_timer
|
60
72
|
@remove_timer = remove_timer
|
73
|
+
@schedule = schedule
|
61
74
|
|
62
|
-
@add_handle_cb = FFI::Event.
|
63
|
-
@update_handle_cb =
|
64
|
-
@remove_handle_cb =
|
65
|
-
@add_timer_cb = FFI::Event.
|
66
|
-
@update_timer_cb =
|
67
|
-
@remove_timer_cb =
|
75
|
+
@add_handle_cb = FFI::Event.callback_function(:virEventAddHandleFunc, &method(:_add_handle))
|
76
|
+
@update_handle_cb = FFI::Event.callback_function(:virEventUpdateHandleFunc, &method(:_update_handle))
|
77
|
+
@remove_handle_cb = FFI::Event.callback_function(:virEventRemoveHandleFunc, &method(:_remove_handle))
|
78
|
+
@add_timer_cb = FFI::Event.callback_function(:virEventAddTimeoutFunc, &method(:_add_timer))
|
79
|
+
@update_timer_cb = FFI::Event.callback_function(:virEventUpdateTimeoutFunc, &method(:_update_timer))
|
80
|
+
@remove_timer_cb = FFI::Event.callback_function(:virEventRemoveTimeoutFunc, &method(:_remove_timer))
|
68
81
|
|
69
82
|
FFI::Event.virEventRegisterImpl(
|
70
83
|
@add_handle_cb,
|
@@ -79,45 +92,54 @@ module Libvirt
|
|
79
92
|
|
80
93
|
private
|
81
94
|
|
82
|
-
def _add_handle(fd, event, cb, opaque,
|
83
|
-
|
84
|
-
op = Opaque.new(cb, opaque,
|
95
|
+
def _add_handle(fd, event, cb, opaque, free_func)
|
96
|
+
dbg { "ADD_HANDLE fd=#{fd}, #{event}=event, cb=#{cb}, opaque=#{opaque}, free_func=#{free_func}" }
|
97
|
+
op = Opaque.new(cb, opaque, free_func)
|
85
98
|
@add_handle.call(fd, event, op)
|
86
99
|
end
|
87
100
|
|
88
101
|
def _update_handle(watch, event)
|
89
|
-
|
102
|
+
dbg { "UPDATE_HANDLE watch=#{watch}, event=#{event}" }
|
90
103
|
@update_handle.call(watch, event)
|
91
104
|
end
|
92
105
|
|
93
106
|
def _remove_handle(watch)
|
94
|
-
|
107
|
+
dbg { "REMOVE_HANDLE watch=#{watch}" }
|
95
108
|
op = @remove_handle.call(watch)
|
96
|
-
free_func = op.
|
109
|
+
free_func = op.free_func
|
97
110
|
opaque = op.opaque
|
98
|
-
|
111
|
+
schedule_operation do
|
112
|
+
dbg { "REMOVE_HANDLE delayed free_func watch=#{watch}" }
|
113
|
+
free_func.call(opaque) unless free_func.null?
|
114
|
+
end
|
99
115
|
0
|
100
116
|
end
|
101
117
|
|
102
|
-
def _add_timer(timeout, cb, opaque,
|
103
|
-
|
104
|
-
op = Opaque.new(cb, opaque,
|
118
|
+
def _add_timer(timeout, cb, opaque, free_func)
|
119
|
+
dbg { "ADD_TIMER timeout=#{timeout}, cb=#{cb}, opaque=#{opaque}, free_func=#{free_func}" }
|
120
|
+
op = Opaque.new(cb, opaque, free_func)
|
105
121
|
@add_timer.call(timeout, op)
|
106
122
|
end
|
107
123
|
|
108
124
|
def _update_timer(timer, timeout)
|
109
|
-
|
125
|
+
dbg { "UPDATE_TIMER timer=#{timer}, timeout=#{timeout}" }
|
110
126
|
@update_timer.call(timer, timeout)
|
111
127
|
end
|
112
128
|
|
113
129
|
def _remove_timer(timer)
|
114
|
-
|
130
|
+
dbg { "REMOVE_TIMER timer=#{timer}" }
|
115
131
|
op = @remove_timer.call(timer)
|
116
|
-
free_func = op.
|
132
|
+
free_func = op.free_func
|
117
133
|
opaque = op.opaque
|
118
|
-
|
134
|
+
schedule_operation do
|
135
|
+
dbg { "REMOVE_TIMER async free_func timer=#{timer}" }
|
136
|
+
free_func.call(opaque) unless free_func.null?
|
137
|
+
end
|
119
138
|
0
|
120
139
|
end
|
121
140
|
|
141
|
+
def dbg(&block)
|
142
|
+
Util.log(:debug, 'Libvirt::Event', &block)
|
143
|
+
end
|
122
144
|
end
|
123
145
|
end
|