class DBus::Main

Main event loop class.

Class that takes care of handling message and signal events asynchronously. Note: This is a native implement and therefore does not integrate with a graphical widget set main loop.

Public Class Methods

new() click to toggle source

Create a new main event loop.

# File lib/dbus/bus.rb, line 873
def initialize
  @buses = Hash.new
  @buses_thread = Array.new
  @quit_queue = Queue.new
  @quitting = false
  $mainclass = self
end

Public Instance Methods

<<(bus) click to toggle source

Add a bus to the list of buses to watch for events.

# File lib/dbus/bus.rb, line 896
def <<(bus)
  @buses[bus.socket] = bus
end
quit() click to toggle source

Quit a running main loop, to be used eg. from a signal handler

# File lib/dbus/bus.rb, line 901
def quit
  if(ENV["DBUS_THREADED_ACCESS"] || false)
    @quitting = true
    quit_imediately
  else
    @quitting = true
  end
end
quit_imediately() click to toggle source

the standar quit method didn’t quit imediately and wait for a last message. This methodes allow to quit imediately

# File lib/dbus/bus.rb, line 883
def quit_imediately 
  @buses.each_value do |b|
    #b.read_thread.exit
  end
  @buses_thread.each do |th|
    @buses_thread_id.delete(th.object_id)
    #th.exit
  end
  @quit_queue << "quit"      

end
run() click to toggle source

Run the main loop. This is a blocking call!

# File lib/dbus/bus.rb, line 911
def run
  # before blocking, empty the buffers
  # https://bugzilla.novell.com/show_bug.cgi?id=537401
  @buses_thread_id = Array.new
  @buses_thread = Array.new
  @thread_as_quit = Queue.new

  if(ENV["DBUS_THREADED_ACCESS"] || false)
    @buses.each_value do |b|
      
      b.rescuemethod = self.method(:quit_imediately)
      th= Thread.new{
        b.main_thread = true
        while m = b.pop_message
          b.process(m)
        end

        while not b.nil? and not @quitting
          m = b.main_message_queue.pop
          b.process(m)
        end

        @thread_as_quit << Thread.current.object_id
      }
      @buses_thread_id.push th.object_id
      @buses_thread.push th
    end
  
    popping_thread =  Thread.new{
      @quit_queue.pop
    }
    popping_thread.join # main thread - sleep for this thread waiting for poping thread
    
   else
    @buses.each_value do |b|

      while m = b.pop_message
        b.process(m)
      end
      
    end
    while not @quitting and not @buses.empty?
      io_ready = false
      while not io_ready and not @quitting and not @buses.empty? do
        ready, dum, dum = IO.select(@buses.keys, nil, nil, 0.1)
        io_ready = !(ready.nil? or ready.first.nil?)
      end

      next if ready.nil?

      ready.each do |socket|
        b = @buses[socket]
        begin
          b.update_buffer
        rescue EOFError, SystemCallError
          @buses.delete socket # this bus died
          next
        end
        while m = b.pop_message
          b.process(m)
        end
      end
    end
    
  end # if($threaded)
end