/
main.rb
73 lines (65 loc) · 1.64 KB
/
main.rb
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
# Based on DBus::Main in ruby-dbus gem.
# Stop the main loop as quick as possible.
require 'sleepy_penguin'
module Kaede
module DBus
class Main
def initialize
@buses = Hash.new
@quit_event = SleepyPenguin::EventFD.new(0, :SEMAPHORE)
end
def <<(bus)
@buses[bus.message_queue.socket] = bus
end
def quit
@quit_event.incr(1)
end
def loop
flush_buffers
epoll = prepare_epoll
begin
while !@buses.empty?
epoll.wait do |events, io|
if io == @quit_event
io.value
return
end
handle_socket(io)
end
end
ensure
epoll.close
end
end
def handle_socket(socket)
bus = @buses[socket]
begin
bus.message_queue.buffer_from_socket_nonblock
rescue EOFError, SystemCallError
@buses.delete(socket) # this bus died
return
end
while message = bus.message_queue.message_from_buffer_nonblock
bus.process(message)
end
end
def flush_buffers
# before blocking, empty the buffers
# https://bugzilla.novell.com/show_bug.cgi?id=537401
@buses.each_value do |b|
while m = b.message_queue.message_from_buffer_nonblock
b.process(m)
end
end
end
def prepare_epoll
SleepyPenguin::Epoll.new.tap do |epoll|
epoll.add(@quit_event, [:IN])
@buses.each_key do |socket|
epoll.add(socket, [:IN])
end
end
end
end
end
end