guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

libdbus mainloop


From: Matt Wette
Subject: libdbus mainloop
Date: Sat, 14 Apr 2018 07:56:05 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

So just goofing around with libdbus.  I did write a mainloop on top of libdbus
and epoll (w/ Guile API provided by the FFI Helper).  I can spawn off a thread
for the loop, fire off a message and poll for the return.  One is supposed to
take care about thread safety with libdbus, and there does not seem to be a lot
of documentation (at least I could not find much).  However, I have generated
thread-safe timeout handlers.  I think it is safe in the way I use it.


mwette$ guile dbus05.scm
there-yet? => #f
there-yet? => #t
result:
  (("Serial" . 59)
   ("ListMemPoolUsedBytes" . 75168)
   ("ListMemPoolCachedBytes" . 7320)
   ("ListMemPoolAllocatedBytes" . 97920)
   ("ActiveConnections" . 75)
   ("IncompleteConnections" . 0)
   ("MatchRules" . 930)
   ("PeakMatchRules" . 1087)
   ("PeakMatchRulesPerConnection" . 188)
   ("BusNames" . 142)
   ("PeakBusNames" . 146)
   ("PeakBusNamesPerConnection" . 7))

mwette$ cat dbus05.scm
;; dbus05.scm - mainloop example

(use-modules (dbus00))
(use-modules (dbusML))
(use-modules (ffi dbus))
(use-modules (system ffi-help-rt))
(use-modules ((system foreign) #:prefix ffi:))
(use-modules (ice-9 pretty-print))

(define (sf fmt . args) (apply simple-format #t fmt args))
(define pp pretty-print)

(define (send-msg conn msg)
  (let ((pending (make-DBusPendingCall*)))
    (if (eqv? FALSE
              (dbus_connection_send_with_reply conn msg (pointer-to pending) 
-1))
        (error "*** send_with_reply FAILED\n"))
    (dbus_message_unref msg)
    pending))

(define (there-yet? pending)
  (eqv? TRUE (dbus_pending_call_get_completed pending)))

(define (handle-it pending)
  (let ((msg (dbus_pending_call_steal_reply pending))
        (msg-iter (make-DBusMessageIter)))
    (if (zero? (fh-object-ref msg)) (error "*** reply message NULL\n"))
    (dbus_pending_call_unref pending)
    (dbus_message_iter_init msg (pointer-to msg-iter))
    (sf "result:\n")
    (pretty-print (read-dbus-val (pointer-to msg-iter)) #:per-line-prefix "  ")
    (dbus_message_unref msg)))

(define (block-and-handle-it pending)
  (dbus_pending_call_block pending)
  (handle-it pending))

;; ==========================================================================

(define conn (spawn-dbus-mainloop 'session))

(define msg (dbus_message_new_method_call
             "org.freedesktop.DBus"           ; bus name
             "/org/freedesktop/DBus"          ; object path
             "org.freedesktop.DBus.Debug.Stats"       ; interface name
             "GetStats"))                     ; method

(define pending (send-msg conn msg))

(let iter ((got-it? (there-yet? pending)))
  (sf "there-yet? => ~S\n" got-it?)
  (cond
   (got-it? (handle-it pending))
   (else
    (sleep 1)
    (iter (there-yet? pending)))))

;; --- last line ---

TO TRY IT:
$ git clone -b c99dev git://git.savannah.nongnu.org/nyacc.git
$ cd nyacc/examples
$ . env.sh
$ guild compile-ffi ffi/epoll.ffi
$ guild compile-ffi ffi/dbus.ffi
$ cd nyacc/lang/c99/ffi-exam
$ guile dbus05.scm [will take some time to compile everything]

[caveat: you may need `.' in your GUILD_LOAD_PATH]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]