ruby-dbus 0.23.0.beta2 → 0.23.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS.md +10 -0
- data/VERSION +1 -1
- data/examples/utils/listnames.rb +9 -1
- data/lib/dbus/bus.rb +92 -5
- data/lib/dbus/connection.rb +21 -8
- data/lib/dbus/object.rb +24 -6
- data/spec/bus_connection_spec.rb +20 -7
- data/spec/mock-service/spaghetti-monster.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2465a9a90d0b4837640d475566edfde23aee4dc1d7d439d76d1f861b71f13033
|
4
|
+
data.tar.gz: 906288ee9d180ff0bfd4e53f45982040f240da983e23c818acd91d449d9f7f05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2939e81cff3f5db2dd768f9e0f1c04159b0285501c73840f14dd8f61ad9f539fbbbf35d7e408cca11847dcd31848131c1c4df69705798860f03e4255f02dedf
|
7
|
+
data.tar.gz: 553f1d4c97a284371d7a10a0f439a40d2861ff8c40c2318c09f6f818f5911644db05142dc7a8d5e377dac355ddc389fcc9858647a568184e8598fd3d3bb71154
|
data/NEWS.md
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## Ruby D-Bus 0.23.1 - 2023-10-03
|
6
|
+
|
7
|
+
API:
|
8
|
+
* Add DBus::Object.dbus_reader_attr_accessor to declare a common use case
|
9
|
+
with a single call ([#140][]).
|
10
|
+
* BusConnection#request_name defaults to the simple use case: single owner
|
11
|
+
without queuing, failing fast; documented the complex use cases.
|
12
|
+
|
13
|
+
[#140]: https://github.com/mvidner/ruby-dbus/pull/140
|
14
|
+
|
5
15
|
## Ruby D-Bus 0.23.0.beta2 - 2023-06-23
|
6
16
|
|
7
17
|
License:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.23.
|
1
|
+
0.23.1
|
data/examples/utils/listnames.rb
CHANGED
@@ -8,4 +8,12 @@ d = if ARGV.member?("--system")
|
|
8
8
|
else
|
9
9
|
DBus::SessionBus.instance
|
10
10
|
end
|
11
|
-
d.proxy.ListNames[0].each
|
11
|
+
d.proxy.ListNames[0].each do |n|
|
12
|
+
puts "\t#{n}"
|
13
|
+
qns = d.proxy.ListQueuedOwners(n)[0]
|
14
|
+
next if qns.size == 1 && qns.first == n
|
15
|
+
|
16
|
+
qns.each do |qn|
|
17
|
+
puts "\t\t#{qn}"
|
18
|
+
end
|
19
|
+
end
|
data/lib/dbus/bus.rb
CHANGED
@@ -55,20 +55,107 @@ module DBus
|
|
55
55
|
@proxy
|
56
56
|
end
|
57
57
|
|
58
|
+
# Request a well-known name so that clients can find us.
|
59
|
+
# @note Parameters other than *name* are advanced, you probably don't need them.
|
60
|
+
#
|
61
|
+
# With no boolean flags, running a second instance of a program that calls `request_name`
|
62
|
+
# will result in the second one failing, which this library translates to an exception.
|
63
|
+
# If you want the second instance to take over, you need both
|
64
|
+
# `allow_replacement: true` and `replace_existing: true.`
|
65
|
+
#
|
58
66
|
# @param name [BusName] the requested name
|
59
|
-
# @param
|
60
|
-
#
|
61
|
-
# @
|
67
|
+
# @param replace_existing [Boolean]
|
68
|
+
# Replace an existing owner of the name, if that owner set *allow_replacement*.
|
69
|
+
# @param allow_replacement [Boolean]
|
70
|
+
# Other connections that specify *replace_existing* will be able to take
|
71
|
+
# the name from us. We will get {#on_name_lost NameLost}. If we specified *queue*
|
72
|
+
# we may get the name again, with {#on_name_acquired NameAcquired}.
|
73
|
+
# @param queue [Boolean]
|
74
|
+
# Affects the behavior when the bus denies the name (sooner or later).
|
75
|
+
# - If `false` (default), it is recommended to let the `NameRequestError` fall through and end your program.
|
76
|
+
# - If `true`, you should `rescue` the `NameRequestError` and set up
|
77
|
+
# {#on_name_acquired NameAcquired} and {#on_name_lost NameLost} handlers.
|
78
|
+
# Meanwhile, the bus will put us in a queue waiting for *name* (this is the "sooner" case).
|
79
|
+
# Also, if we had `allow_replacement: true`, another connection can cause us
|
80
|
+
# to lose the name. We will be moved back to the queue, waiting for when the other owners give up
|
81
|
+
# (the "later" case).
|
82
|
+
# @param flags [Integer,nil]
|
83
|
+
# If specified, overrides the boolean parameters.
|
84
|
+
# Use a bitwise sum `|` of:
|
85
|
+
# - NAME_FLAG_ALLOW_REPLACEMENT
|
86
|
+
# - NAME_FLAG_REPLACE_EXISTING
|
87
|
+
# - NAME_FLAG_DO_NOT_QUEUE
|
88
|
+
# Note that `0` implies `queue: true`.
|
89
|
+
#
|
90
|
+
# @return [REQUEST_NAME_REPLY_PRIMARY_OWNER,REQUEST_NAME_REPLY_ALREADY_OWNER] on success
|
91
|
+
# @raise [NameRequestError] with #error_code REQUEST_NAME_REPLY_EXISTS or REQUEST_NAME_REPLY_IN_QUEUE, on failure
|
92
|
+
# @raise DBus::Error another way to fail is being prohibited to own the name
|
93
|
+
# which is the default on the system bus
|
94
|
+
#
|
95
|
+
# @see https://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-request-name
|
96
|
+
#
|
97
|
+
# @example Simple usage
|
62
98
|
# bus = DBus.session_bus
|
63
99
|
# bus.object_server.export(DBus::Object.new("/org/example/Test"))
|
64
100
|
# bus.request_name("org.example.Test")
|
65
|
-
#
|
66
|
-
|
101
|
+
# # main loop
|
102
|
+
#
|
103
|
+
# @example Second instance taking over
|
104
|
+
# bus = DBus.session_bus
|
105
|
+
# bus.object_server.export(DBus::Object.new("/org/example/Test"))
|
106
|
+
# bus.on_name_lost { exit }
|
107
|
+
# bus.request_name("org.example.Test", allow_replacement: true, replace_existing: true)
|
108
|
+
# # main loop
|
109
|
+
#
|
110
|
+
# @example Second instance waiting for its turn
|
111
|
+
# bus = DBus.session_bus
|
112
|
+
# bus.object_server.export(DBus::Object.new("/org/example/Test"))
|
113
|
+
# bus.on_name_acquired { @owner = true }
|
114
|
+
# begin
|
115
|
+
# bus.request_name("org.example.Test", queue: true)
|
116
|
+
# rescue DBus::Connection::NameRequestError => e
|
117
|
+
# @owner = false
|
118
|
+
# end
|
119
|
+
# # main loop
|
120
|
+
def request_name(name,
|
121
|
+
allow_replacement: false,
|
122
|
+
replace_existing: false,
|
123
|
+
queue: false,
|
124
|
+
flags: nil)
|
125
|
+
if flags.nil?
|
126
|
+
flags = (allow_replacement ? NAME_FLAG_ALLOW_REPLACEMENT : 0) |
|
127
|
+
(replace_existing ? NAME_FLAG_REPLACE_EXISTING : 0) |
|
128
|
+
(queue ? 0 : NAME_FLAG_DO_NOT_QUEUE)
|
129
|
+
end
|
67
130
|
name = BusName.new(name)
|
68
131
|
r = proxy.RequestName(name, flags).first
|
69
132
|
handle_return_of_request_name(r, name)
|
70
133
|
end
|
71
134
|
|
135
|
+
# The caller has released his claim on the given name.
|
136
|
+
# Either the caller was the primary owner of the name, and the name is now unused
|
137
|
+
# or taken by somebody waiting in the queue for the name,
|
138
|
+
# or the caller was waiting in the queue for the name and has now been removed from the queue.
|
139
|
+
RELEASE_NAME_REPLY_RELEASED = 1
|
140
|
+
# The given name does not exist on this bus.
|
141
|
+
RELEASE_NAME_REPLY_NON_EXISTENT = 2
|
142
|
+
# The caller was not the primary owner of this name, and was also not waiting in the queue to own this name.
|
143
|
+
RELEASE_NAME_REPLY_NOT_OWNER = 3
|
144
|
+
|
145
|
+
# @param name [BusName] the name to release
|
146
|
+
def release_name(name)
|
147
|
+
name = BusName.new(name)
|
148
|
+
proxy.ReleaseName(name).first
|
149
|
+
end
|
150
|
+
|
151
|
+
def on_name_acquired(&handler)
|
152
|
+
proxy.on_signal("NameAcquired", &handler)
|
153
|
+
end
|
154
|
+
|
155
|
+
def on_name_lost(&handler)
|
156
|
+
proxy.on_signal("NameLost", &handler)
|
157
|
+
end
|
158
|
+
|
72
159
|
# Asks bus to send us messages matching mr, and execute slot when
|
73
160
|
# received
|
74
161
|
# @param match_rule [MatchRule,#to_s]
|
data/lib/dbus/connection.rb
CHANGED
@@ -153,17 +153,30 @@ module DBus
|
|
153
153
|
|
154
154
|
# Exception raised when a service name is requested that is not available.
|
155
155
|
class NameRequestError < Exception
|
156
|
+
# @return [Integer] one of
|
157
|
+
# REQUEST_NAME_REPLY_IN_QUEUE
|
158
|
+
# REQUEST_NAME_REPLY_EXISTS
|
159
|
+
attr_reader :error_code
|
160
|
+
|
161
|
+
def initialize(error_code)
|
162
|
+
@error_code = error_code
|
163
|
+
super()
|
164
|
+
end
|
156
165
|
end
|
157
166
|
|
167
|
+
# In case RequestName did not succeed, raise an exception but first ask the bus who owns the name instead of us
|
168
|
+
# @param ret [Integer] what RequestName returned
|
169
|
+
# @param name Name that was requested
|
170
|
+
# @return [REQUEST_NAME_REPLY_PRIMARY_OWNER,REQUEST_NAME_REPLY_ALREADY_OWNER] on success
|
171
|
+
# @raise [NameRequestError] with #error_code REQUEST_NAME_REPLY_EXISTS or REQUEST_NAME_REPLY_IN_QUEUE, on failure
|
172
|
+
# @api private
|
158
173
|
def handle_return_of_request_name(ret, name)
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
166
|
-
raise NameRequestError, "Could not request #{name}, #{details}" unless ret == REQUEST_NAME_REPLY_PRIMARY_OWNER
|
174
|
+
if [REQUEST_NAME_REPLY_EXISTS, REQUEST_NAME_REPLY_IN_QUEUE].include?(ret)
|
175
|
+
other = proxy.GetNameOwner(name).first
|
176
|
+
other_creds = proxy.GetConnectionCredentials(other).first
|
177
|
+
message = "Could not request #{name}, already owned by #{other}, #{other_creds.inspect}"
|
178
|
+
raise NameRequestError.new(ret), message
|
179
|
+
end
|
167
180
|
|
168
181
|
ret
|
169
182
|
end
|
data/lib/dbus/object.rb
CHANGED
@@ -156,18 +156,32 @@ module DBus
|
|
156
156
|
dbus_accessor(ruby_name, type, dbus_name: dbus_name, emits_changed_signal: emits_changed_signal)
|
157
157
|
end
|
158
158
|
|
159
|
+
# A read-only property accessing a read-write instance variable.
|
160
|
+
# A combination of `attr_accessor` and {.dbus_reader}.
|
161
|
+
#
|
162
|
+
# @param (see .dbus_attr_accessor)
|
163
|
+
# @return (see .dbus_attr_accessor)
|
164
|
+
def self.dbus_reader_attr_accessor(ruby_name, type, dbus_name: nil, emits_changed_signal: nil)
|
165
|
+
attr_accessor(ruby_name)
|
166
|
+
|
167
|
+
dbus_reader(ruby_name, type, dbus_name: dbus_name, emits_changed_signal: emits_changed_signal)
|
168
|
+
end
|
169
|
+
|
159
170
|
# A read-only property accessing an instance variable.
|
160
171
|
# A combination of `attr_reader` and {.dbus_reader}.
|
161
172
|
#
|
173
|
+
# You may be instead looking for a variant which is read-write from the Ruby side:
|
174
|
+
# {.dbus_reader_attr_accessor}.
|
175
|
+
#
|
162
176
|
# Whenever the property value gets changed from "inside" the object,
|
163
177
|
# you should emit the `PropertiesChanged` signal by calling
|
164
178
|
# {#dbus_properties_changed}.
|
165
179
|
#
|
166
|
-
#
|
180
|
+
# dbus_properties_changed(interface_name, {dbus_name.to_s => value}, [])
|
167
181
|
#
|
168
182
|
# or, omitting the value in the signal,
|
169
183
|
#
|
170
|
-
#
|
184
|
+
# dbus_properties_changed(interface_name, {}, [dbus_name.to_s])
|
171
185
|
#
|
172
186
|
# @param (see .dbus_attr_accessor)
|
173
187
|
# @return (see .dbus_attr_accessor)
|
@@ -213,18 +227,22 @@ module DBus
|
|
213
227
|
# implement it with a read-write attr_accessor. In that case this method
|
214
228
|
# uses {.dbus_watcher} to set up the PropertiesChanged signal.
|
215
229
|
#
|
216
|
-
#
|
217
|
-
#
|
230
|
+
# attr_accessor :foo_bar
|
231
|
+
# dbus_reader :foo_bar, "s"
|
232
|
+
#
|
233
|
+
# The above two declarations have a shorthand:
|
234
|
+
#
|
235
|
+
# dbus_reader_attr_accessor :foo_bar, "s"
|
218
236
|
#
|
219
237
|
# If the property value should change by other means than its attr_writer,
|
220
238
|
# you should emit the `PropertiesChanged` signal by calling
|
221
239
|
# {#dbus_properties_changed}.
|
222
240
|
#
|
223
|
-
#
|
241
|
+
# dbus_properties_changed(interface_name, {dbus_name.to_s => value}, [])
|
224
242
|
#
|
225
243
|
# or, omitting the value in the signal,
|
226
244
|
#
|
227
|
-
#
|
245
|
+
# dbus_properties_changed(interface_name, {}, [dbus_name.to_s])
|
228
246
|
#
|
229
247
|
# @param (see .dbus_attr_accessor)
|
230
248
|
# @return (see .dbus_attr_accessor)
|
data/spec/bus_connection_spec.rb
CHANGED
@@ -21,7 +21,6 @@ describe DBus::BusConnection do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
context "when the name is taken already", tag_service: true do
|
24
|
-
# formerly it returned Service, now ObjectServer takes its role
|
25
24
|
it "raises NameRequestError... too late" do
|
26
25
|
name = "org.ruby.service"
|
27
26
|
expect do
|
@@ -50,21 +49,35 @@ describe DBus::BusConnection do
|
|
50
49
|
|
51
50
|
describe "#request_name", tag_bus: true do
|
52
51
|
context "when the name request succeeds" do
|
53
|
-
it "returns
|
52
|
+
it "returns a success code" do
|
54
53
|
name = "org.rubygems.ruby_dbus.RequestNameTest"
|
55
|
-
expect
|
56
|
-
|
54
|
+
expect(bus.request_name(name)).to eq DBus::Connection::REQUEST_NAME_REPLY_PRIMARY_OWNER
|
55
|
+
# second time, considered also a success
|
56
|
+
expect(bus.request_name(name)).to eq DBus::Connection::REQUEST_NAME_REPLY_ALREADY_OWNER
|
57
|
+
bus.release_name(name)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
61
|
context "when the name is taken already", tag_service: true do
|
61
|
-
# formerly it returned Service, now ObjectServer takes its role
|
62
62
|
it "raises NameRequestError" do
|
63
63
|
name = "org.ruby.service"
|
64
64
|
expect do
|
65
|
-
|
66
|
-
|
65
|
+
bus.request_name(name)
|
66
|
+
end.to raise_error(DBus::Connection::NameRequestError)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when the name is taken already but we request queuing", tag_service: true do
|
71
|
+
it "raises NameRequestError but we are queued" do
|
72
|
+
name = "org.ruby.service"
|
73
|
+
owning = nil
|
74
|
+
# TODO: we do not expect the handlers to run
|
75
|
+
bus.on_name_acquired { owning = true }
|
76
|
+
bus.on_name_lost { owning = false }
|
77
|
+
expect do
|
78
|
+
bus.request_name(name, queue: true)
|
67
79
|
end.to raise_error(DBus::Connection::NameRequestError)
|
80
|
+
expect(bus.release_name(name)).to eq DBus::BusConnection::RELEASE_NAME_REPLY_RELEASED
|
68
81
|
end
|
69
82
|
end
|
70
83
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dbus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruby DBus Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rexml
|
@@ -235,9 +235,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
235
235
|
version: 2.4.0
|
236
236
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
237
|
requirements:
|
238
|
-
- - "
|
238
|
+
- - ">="
|
239
239
|
- !ruby/object:Gem::Version
|
240
|
-
version:
|
240
|
+
version: '0'
|
241
241
|
requirements: []
|
242
242
|
rubygems_version: 3.3.26
|
243
243
|
signing_key:
|