conn.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. package dbus
  2. import (
  3. "context"
  4. "errors"
  5. "io"
  6. "os"
  7. "reflect"
  8. "strings"
  9. "sync"
  10. )
  11. var (
  12. systemBus *Conn
  13. systemBusLck sync.Mutex
  14. sessionBus *Conn
  15. sessionBusLck sync.Mutex
  16. )
  17. // ErrClosed is the error returned by calls on a closed connection.
  18. var ErrClosed = errors.New("dbus: connection closed by user")
  19. // Conn represents a connection to a message bus (usually, the system or
  20. // session bus).
  21. //
  22. // Connections are either shared or private. Shared connections
  23. // are shared between calls to the functions that return them. As a result,
  24. // the methods Close, Auth and Hello must not be called on them.
  25. //
  26. // Multiple goroutines may invoke methods on a connection simultaneously.
  27. type Conn struct {
  28. transport
  29. busObj BusObject
  30. unixFD bool
  31. uuid string
  32. handler Handler
  33. signalHandler SignalHandler
  34. serialGen SerialGenerator
  35. names *nameTracker
  36. calls *callTracker
  37. outHandler *outputHandler
  38. eavesdropped chan<- *Message
  39. eavesdroppedLck sync.Mutex
  40. }
  41. // SessionBus returns a shared connection to the session bus, connecting to it
  42. // if not already done.
  43. func SessionBus() (conn *Conn, err error) {
  44. sessionBusLck.Lock()
  45. defer sessionBusLck.Unlock()
  46. if sessionBus != nil {
  47. return sessionBus, nil
  48. }
  49. defer func() {
  50. if conn != nil {
  51. sessionBus = conn
  52. }
  53. }()
  54. conn, err = SessionBusPrivate()
  55. if err != nil {
  56. return
  57. }
  58. if err = conn.Auth(nil); err != nil {
  59. conn.Close()
  60. conn = nil
  61. return
  62. }
  63. if err = conn.Hello(); err != nil {
  64. conn.Close()
  65. conn = nil
  66. }
  67. return
  68. }
  69. func getSessionBusAddress() (string, error) {
  70. if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
  71. return address, nil
  72. } else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
  73. os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
  74. return address, nil
  75. }
  76. return getSessionBusPlatformAddress()
  77. }
  78. // SessionBusPrivate returns a new private connection to the session bus.
  79. func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
  80. address, err := getSessionBusAddress()
  81. if err != nil {
  82. return nil, err
  83. }
  84. return Dial(address, opts...)
  85. }
  86. // SessionBusPrivate returns a new private connection to the session bus.
  87. //
  88. // Deprecated: use SessionBusPrivate with options instead.
  89. func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
  90. return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
  91. }
  92. // SystemBus returns a shared connection to the system bus, connecting to it if
  93. // not already done.
  94. func SystemBus() (conn *Conn, err error) {
  95. systemBusLck.Lock()
  96. defer systemBusLck.Unlock()
  97. if systemBus != nil {
  98. return systemBus, nil
  99. }
  100. defer func() {
  101. if conn != nil {
  102. systemBus = conn
  103. }
  104. }()
  105. conn, err = SystemBusPrivate()
  106. if err != nil {
  107. return
  108. }
  109. if err = conn.Auth(nil); err != nil {
  110. conn.Close()
  111. conn = nil
  112. return
  113. }
  114. if err = conn.Hello(); err != nil {
  115. conn.Close()
  116. conn = nil
  117. }
  118. return
  119. }
  120. // SystemBusPrivate returns a new private connection to the system bus.
  121. func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
  122. return Dial(getSystemBusPlatformAddress(), opts...)
  123. }
  124. // SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers.
  125. //
  126. // Deprecated: use SystemBusPrivate with options instead.
  127. func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
  128. return SystemBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
  129. }
  130. // Dial establishes a new private connection to the message bus specified by address.
  131. func Dial(address string, opts ...ConnOption) (*Conn, error) {
  132. tr, err := getTransport(address)
  133. if err != nil {
  134. return nil, err
  135. }
  136. return newConn(tr, opts...)
  137. }
  138. // DialHandler establishes a new private connection to the message bus specified by address, using the supplied handlers.
  139. //
  140. // Deprecated: use Dial with options instead.
  141. func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
  142. return Dial(address, WithSignalHandler(signalHandler))
  143. }
  144. // ConnOption is a connection option.
  145. type ConnOption func(conn *Conn) error
  146. // WithHandler overrides the default handler.
  147. func WithHandler(handler Handler) ConnOption {
  148. return func(conn *Conn) error {
  149. conn.handler = handler
  150. return nil
  151. }
  152. }
  153. // WithSignalHandler overrides the default signal handler.
  154. func WithSignalHandler(handler SignalHandler) ConnOption {
  155. return func(conn *Conn) error {
  156. conn.signalHandler = handler
  157. return nil
  158. }
  159. }
  160. // WithSerialGenerator overrides the default signals generator.
  161. func WithSerialGenerator(gen SerialGenerator) ConnOption {
  162. return func(conn *Conn) error {
  163. conn.serialGen = gen
  164. return nil
  165. }
  166. }
  167. // NewConn creates a new private *Conn from an already established connection.
  168. func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
  169. return newConn(genericTransport{conn}, opts...)
  170. }
  171. // NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers.
  172. //
  173. // Deprecated: use NewConn with options instead.
  174. func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
  175. return NewConn(genericTransport{conn}, WithHandler(handler), WithSignalHandler(signalHandler))
  176. }
  177. // newConn creates a new *Conn from a transport.
  178. func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
  179. conn := new(Conn)
  180. conn.transport = tr
  181. for _, opt := range opts {
  182. if err := opt(conn); err != nil {
  183. return nil, err
  184. }
  185. }
  186. conn.calls = newCallTracker()
  187. if conn.handler == nil {
  188. conn.handler = NewDefaultHandler()
  189. }
  190. if conn.signalHandler == nil {
  191. conn.signalHandler = NewDefaultSignalHandler()
  192. }
  193. if conn.serialGen == nil {
  194. conn.serialGen = newSerialGenerator()
  195. }
  196. conn.outHandler = &outputHandler{conn: conn}
  197. conn.names = newNameTracker()
  198. conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
  199. return conn, nil
  200. }
  201. // BusObject returns the object owned by the bus daemon which handles
  202. // administrative requests.
  203. func (conn *Conn) BusObject() BusObject {
  204. return conn.busObj
  205. }
  206. // Close closes the connection. Any blocked operations will return with errors
  207. // and the channels passed to Eavesdrop and Signal are closed. This method must
  208. // not be called on shared connections.
  209. func (conn *Conn) Close() error {
  210. conn.outHandler.close()
  211. if term, ok := conn.signalHandler.(Terminator); ok {
  212. term.Terminate()
  213. }
  214. if term, ok := conn.handler.(Terminator); ok {
  215. term.Terminate()
  216. }
  217. conn.eavesdroppedLck.Lock()
  218. if conn.eavesdropped != nil {
  219. close(conn.eavesdropped)
  220. }
  221. conn.eavesdroppedLck.Unlock()
  222. return conn.transport.Close()
  223. }
  224. // Eavesdrop causes conn to send all incoming messages to the given channel
  225. // without further processing. Method replies, errors and signals will not be
  226. // sent to the appropiate channels and method calls will not be handled. If nil
  227. // is passed, the normal behaviour is restored.
  228. //
  229. // The caller has to make sure that ch is sufficiently buffered;
  230. // if a message arrives when a write to ch is not possible, the message is
  231. // discarded.
  232. func (conn *Conn) Eavesdrop(ch chan<- *Message) {
  233. conn.eavesdroppedLck.Lock()
  234. conn.eavesdropped = ch
  235. conn.eavesdroppedLck.Unlock()
  236. }
  237. // GetSerial returns an unused serial.
  238. func (conn *Conn) getSerial() uint32 {
  239. return conn.serialGen.GetSerial()
  240. }
  241. // Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
  242. // called after authentication, but before sending any other messages to the
  243. // bus. Hello must not be called for shared connections.
  244. func (conn *Conn) Hello() error {
  245. var s string
  246. err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
  247. if err != nil {
  248. return err
  249. }
  250. conn.names.acquireUniqueConnectionName(s)
  251. return nil
  252. }
  253. // inWorker runs in an own goroutine, reading incoming messages from the
  254. // transport and dispatching them appropiately.
  255. func (conn *Conn) inWorker() {
  256. for {
  257. msg, err := conn.ReadMessage()
  258. if err != nil {
  259. if _, ok := err.(InvalidMessageError); !ok {
  260. // Some read error occured (usually EOF); we can't really do
  261. // anything but to shut down all stuff and returns errors to all
  262. // pending replies.
  263. conn.Close()
  264. conn.calls.finalizeAllWithError(err)
  265. return
  266. }
  267. // invalid messages are ignored
  268. continue
  269. }
  270. conn.eavesdroppedLck.Lock()
  271. if conn.eavesdropped != nil {
  272. select {
  273. case conn.eavesdropped <- msg:
  274. default:
  275. }
  276. conn.eavesdroppedLck.Unlock()
  277. continue
  278. }
  279. conn.eavesdroppedLck.Unlock()
  280. dest, _ := msg.Headers[FieldDestination].value.(string)
  281. found := dest == "" ||
  282. !conn.names.uniqueNameIsKnown() ||
  283. conn.names.isKnownName(dest)
  284. if !found {
  285. // Eavesdropped a message, but no channel for it is registered.
  286. // Ignore it.
  287. continue
  288. }
  289. switch msg.Type {
  290. case TypeError:
  291. conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg))
  292. case TypeMethodReply:
  293. conn.serialGen.RetireSerial(conn.calls.handleReply(msg))
  294. case TypeSignal:
  295. conn.handleSignal(msg)
  296. case TypeMethodCall:
  297. go conn.handleCall(msg)
  298. }
  299. }
  300. }
  301. func (conn *Conn) handleSignal(msg *Message) {
  302. iface := msg.Headers[FieldInterface].value.(string)
  303. member := msg.Headers[FieldMember].value.(string)
  304. // as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
  305. // sender is optional for signals.
  306. sender, _ := msg.Headers[FieldSender].value.(string)
  307. if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
  308. if member == "NameLost" {
  309. // If we lost the name on the bus, remove it from our
  310. // tracking list.
  311. name, ok := msg.Body[0].(string)
  312. if !ok {
  313. panic("Unable to read the lost name")
  314. }
  315. conn.names.loseName(name)
  316. } else if member == "NameAcquired" {
  317. // If we acquired the name on the bus, add it to our
  318. // tracking list.
  319. name, ok := msg.Body[0].(string)
  320. if !ok {
  321. panic("Unable to read the acquired name")
  322. }
  323. conn.names.acquireName(name)
  324. }
  325. }
  326. signal := &Signal{
  327. Sender: sender,
  328. Path: msg.Headers[FieldPath].value.(ObjectPath),
  329. Name: iface + "." + member,
  330. Body: msg.Body,
  331. }
  332. conn.signalHandler.DeliverSignal(iface, member, signal)
  333. }
  334. // Names returns the list of all names that are currently owned by this
  335. // connection. The slice is always at least one element long, the first element
  336. // being the unique name of the connection.
  337. func (conn *Conn) Names() []string {
  338. return conn.names.listKnownNames()
  339. }
  340. // Object returns the object identified by the given destination name and path.
  341. func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
  342. return &Object{conn, dest, path}
  343. }
  344. // outWorker runs in an own goroutine, encoding and sending messages that are
  345. // sent to conn.out.
  346. func (conn *Conn) sendMessage(msg *Message) {
  347. conn.sendMessageAndIfClosed(msg, func() {})
  348. }
  349. func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
  350. err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
  351. conn.calls.handleSendError(msg, err)
  352. if err != nil {
  353. conn.serialGen.RetireSerial(msg.serial)
  354. } else if msg.Type != TypeMethodCall {
  355. conn.serialGen.RetireSerial(msg.serial)
  356. }
  357. }
  358. // Send sends the given message to the message bus. You usually don't need to
  359. // use this; use the higher-level equivalents (Call / Go, Emit and Export)
  360. // instead. If msg is a method call and NoReplyExpected is not set, a non-nil
  361. // call is returned and the same value is sent to ch (which must be buffered)
  362. // once the call is complete. Otherwise, ch is ignored and a Call structure is
  363. // returned of which only the Err member is valid.
  364. func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
  365. return conn.send(context.Background(), msg, ch)
  366. }
  367. // SendWithContext acts like Send but takes a context
  368. func (conn *Conn) SendWithContext(ctx context.Context, msg *Message, ch chan *Call) *Call {
  369. return conn.send(ctx, msg, ch)
  370. }
  371. func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
  372. if ctx == nil {
  373. panic("nil context")
  374. }
  375. var call *Call
  376. ctx, canceler := context.WithCancel(ctx)
  377. msg.serial = conn.getSerial()
  378. if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
  379. if ch == nil {
  380. ch = make(chan *Call, 5)
  381. } else if cap(ch) == 0 {
  382. panic("dbus: unbuffered channel passed to (*Conn).Send")
  383. }
  384. call = new(Call)
  385. call.Destination, _ = msg.Headers[FieldDestination].value.(string)
  386. call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
  387. iface, _ := msg.Headers[FieldInterface].value.(string)
  388. member, _ := msg.Headers[FieldMember].value.(string)
  389. call.Method = iface + "." + member
  390. call.Args = msg.Body
  391. call.Done = ch
  392. call.ctx = ctx
  393. call.ctxCanceler = canceler
  394. conn.calls.track(msg.serial, call)
  395. go func() {
  396. <-ctx.Done()
  397. conn.calls.handleSendError(msg, ctx.Err())
  398. }()
  399. conn.sendMessageAndIfClosed(msg, func() {
  400. conn.calls.handleSendError(msg, ErrClosed)
  401. canceler()
  402. })
  403. } else {
  404. canceler()
  405. call = &Call{Err: nil}
  406. conn.sendMessageAndIfClosed(msg, func() {
  407. call = &Call{Err: ErrClosed}
  408. })
  409. }
  410. return call
  411. }
  412. // sendError creates an error message corresponding to the parameters and sends
  413. // it to conn.out.
  414. func (conn *Conn) sendError(err error, dest string, serial uint32) {
  415. var e *Error
  416. switch em := err.(type) {
  417. case Error:
  418. e = &em
  419. case *Error:
  420. e = em
  421. case DBusError:
  422. name, body := em.DBusError()
  423. e = NewError(name, body)
  424. default:
  425. e = MakeFailedError(err)
  426. }
  427. msg := new(Message)
  428. msg.Type = TypeError
  429. msg.serial = conn.getSerial()
  430. msg.Headers = make(map[HeaderField]Variant)
  431. if dest != "" {
  432. msg.Headers[FieldDestination] = MakeVariant(dest)
  433. }
  434. msg.Headers[FieldErrorName] = MakeVariant(e.Name)
  435. msg.Headers[FieldReplySerial] = MakeVariant(serial)
  436. msg.Body = e.Body
  437. if len(e.Body) > 0 {
  438. msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
  439. }
  440. conn.sendMessage(msg)
  441. }
  442. // sendReply creates a method reply message corresponding to the parameters and
  443. // sends it to conn.out.
  444. func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
  445. msg := new(Message)
  446. msg.Type = TypeMethodReply
  447. msg.serial = conn.getSerial()
  448. msg.Headers = make(map[HeaderField]Variant)
  449. if dest != "" {
  450. msg.Headers[FieldDestination] = MakeVariant(dest)
  451. }
  452. msg.Headers[FieldReplySerial] = MakeVariant(serial)
  453. msg.Body = values
  454. if len(values) > 0 {
  455. msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
  456. }
  457. conn.sendMessage(msg)
  458. }
  459. func (conn *Conn) defaultSignalAction(fn func(h *defaultSignalHandler, ch chan<- *Signal), ch chan<- *Signal) {
  460. if !isDefaultSignalHandler(conn.signalHandler) {
  461. return
  462. }
  463. handler := conn.signalHandler.(*defaultSignalHandler)
  464. fn(handler, ch)
  465. }
  466. // Signal registers the given channel to be passed all received signal messages.
  467. // The caller has to make sure that ch is sufficiently buffered; if a message
  468. // arrives when a write to c is not possible, it is discarded.
  469. //
  470. // Multiple of these channels can be registered at the same time.
  471. //
  472. // These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
  473. // channel for eavesdropped messages, this channel receives all signals, and
  474. // none of the channels passed to Signal will receive any signals.
  475. func (conn *Conn) Signal(ch chan<- *Signal) {
  476. conn.defaultSignalAction((*defaultSignalHandler).addSignal, ch)
  477. }
  478. // RemoveSignal removes the given channel from the list of the registered channels.
  479. func (conn *Conn) RemoveSignal(ch chan<- *Signal) {
  480. conn.defaultSignalAction((*defaultSignalHandler).removeSignal, ch)
  481. }
  482. // SupportsUnixFDs returns whether the underlying transport supports passing of
  483. // unix file descriptors. If this is false, method calls containing unix file
  484. // descriptors will return an error and emitted signals containing them will
  485. // not be sent.
  486. func (conn *Conn) SupportsUnixFDs() bool {
  487. return conn.unixFD
  488. }
  489. // Error represents a D-Bus message of type Error.
  490. type Error struct {
  491. Name string
  492. Body []interface{}
  493. }
  494. func NewError(name string, body []interface{}) *Error {
  495. return &Error{name, body}
  496. }
  497. func (e Error) Error() string {
  498. if len(e.Body) >= 1 {
  499. s, ok := e.Body[0].(string)
  500. if ok {
  501. return s
  502. }
  503. }
  504. return e.Name
  505. }
  506. // Signal represents a D-Bus message of type Signal. The name member is given in
  507. // "interface.member" notation, e.g. org.freedesktop.D-Bus.NameLost.
  508. type Signal struct {
  509. Sender string
  510. Path ObjectPath
  511. Name string
  512. Body []interface{}
  513. }
  514. // transport is a D-Bus transport.
  515. type transport interface {
  516. // Read and Write raw data (for example, for the authentication protocol).
  517. io.ReadWriteCloser
  518. // Send the initial null byte used for the EXTERNAL mechanism.
  519. SendNullByte() error
  520. // Returns whether this transport supports passing Unix FDs.
  521. SupportsUnixFDs() bool
  522. // Signal the transport that Unix FD passing is enabled for this connection.
  523. EnableUnixFDs()
  524. // Read / send a message, handling things like Unix FDs.
  525. ReadMessage() (*Message, error)
  526. SendMessage(*Message) error
  527. }
  528. var (
  529. transports = make(map[string]func(string) (transport, error))
  530. )
  531. func getTransport(address string) (transport, error) {
  532. var err error
  533. var t transport
  534. addresses := strings.Split(address, ";")
  535. for _, v := range addresses {
  536. i := strings.IndexRune(v, ':')
  537. if i == -1 {
  538. err = errors.New("dbus: invalid bus address (no transport)")
  539. continue
  540. }
  541. f := transports[v[:i]]
  542. if f == nil {
  543. err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
  544. continue
  545. }
  546. t, err = f(v[i+1:])
  547. if err == nil {
  548. return t, nil
  549. }
  550. }
  551. return nil, err
  552. }
  553. // dereferenceAll returns a slice that, assuming that vs is a slice of pointers
  554. // of arbitrary types, containes the values that are obtained from dereferencing
  555. // all elements in vs.
  556. func dereferenceAll(vs []interface{}) []interface{} {
  557. for i := range vs {
  558. v := reflect.ValueOf(vs[i])
  559. v = v.Elem()
  560. vs[i] = v.Interface()
  561. }
  562. return vs
  563. }
  564. // getKey gets a key from a the list of keys. Returns "" on error / not found...
  565. func getKey(s, key string) string {
  566. for _, keyEqualsValue := range strings.Split(s, ",") {
  567. keyValue := strings.SplitN(keyEqualsValue, "=", 2)
  568. if len(keyValue) == 2 && keyValue[0] == key {
  569. return keyValue[1]
  570. }
  571. }
  572. return ""
  573. }
  574. type outputHandler struct {
  575. conn *Conn
  576. sendLck sync.Mutex
  577. closed struct {
  578. isClosed bool
  579. lck sync.RWMutex
  580. }
  581. }
  582. func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error {
  583. h.closed.lck.RLock()
  584. defer h.closed.lck.RUnlock()
  585. if h.closed.isClosed {
  586. ifClosed()
  587. return nil
  588. }
  589. h.sendLck.Lock()
  590. defer h.sendLck.Unlock()
  591. return h.conn.SendMessage(msg)
  592. }
  593. func (h *outputHandler) close() {
  594. h.closed.lck.Lock()
  595. defer h.closed.lck.Unlock()
  596. h.closed.isClosed = true
  597. }
  598. type serialGenerator struct {
  599. lck sync.Mutex
  600. nextSerial uint32
  601. serialUsed map[uint32]bool
  602. }
  603. func newSerialGenerator() *serialGenerator {
  604. return &serialGenerator{
  605. serialUsed: map[uint32]bool{0: true},
  606. nextSerial: 1,
  607. }
  608. }
  609. func (gen *serialGenerator) GetSerial() uint32 {
  610. gen.lck.Lock()
  611. defer gen.lck.Unlock()
  612. n := gen.nextSerial
  613. for gen.serialUsed[n] {
  614. n++
  615. }
  616. gen.serialUsed[n] = true
  617. gen.nextSerial = n + 1
  618. return n
  619. }
  620. func (gen *serialGenerator) RetireSerial(serial uint32) {
  621. gen.lck.Lock()
  622. defer gen.lck.Unlock()
  623. delete(gen.serialUsed, serial)
  624. }
  625. type nameTracker struct {
  626. lck sync.RWMutex
  627. unique string
  628. names map[string]struct{}
  629. }
  630. func newNameTracker() *nameTracker {
  631. return &nameTracker{names: map[string]struct{}{}}
  632. }
  633. func (tracker *nameTracker) acquireUniqueConnectionName(name string) {
  634. tracker.lck.Lock()
  635. defer tracker.lck.Unlock()
  636. tracker.unique = name
  637. }
  638. func (tracker *nameTracker) acquireName(name string) {
  639. tracker.lck.Lock()
  640. defer tracker.lck.Unlock()
  641. tracker.names[name] = struct{}{}
  642. }
  643. func (tracker *nameTracker) loseName(name string) {
  644. tracker.lck.Lock()
  645. defer tracker.lck.Unlock()
  646. delete(tracker.names, name)
  647. }
  648. func (tracker *nameTracker) uniqueNameIsKnown() bool {
  649. tracker.lck.RLock()
  650. defer tracker.lck.RUnlock()
  651. return tracker.unique != ""
  652. }
  653. func (tracker *nameTracker) isKnownName(name string) bool {
  654. tracker.lck.RLock()
  655. defer tracker.lck.RUnlock()
  656. _, ok := tracker.names[name]
  657. return ok || name == tracker.unique
  658. }
  659. func (tracker *nameTracker) listKnownNames() []string {
  660. tracker.lck.RLock()
  661. defer tracker.lck.RUnlock()
  662. out := make([]string, 0, len(tracker.names)+1)
  663. out = append(out, tracker.unique)
  664. for k := range tracker.names {
  665. out = append(out, k)
  666. }
  667. return out
  668. }
  669. type callTracker struct {
  670. calls map[uint32]*Call
  671. lck sync.RWMutex
  672. }
  673. func newCallTracker() *callTracker {
  674. return &callTracker{calls: map[uint32]*Call{}}
  675. }
  676. func (tracker *callTracker) track(sn uint32, call *Call) {
  677. tracker.lck.Lock()
  678. tracker.calls[sn] = call
  679. tracker.lck.Unlock()
  680. }
  681. func (tracker *callTracker) handleReply(msg *Message) uint32 {
  682. serial := msg.Headers[FieldReplySerial].value.(uint32)
  683. tracker.lck.RLock()
  684. _, ok := tracker.calls[serial]
  685. tracker.lck.RUnlock()
  686. if ok {
  687. tracker.finalizeWithBody(serial, msg.Body)
  688. }
  689. return serial
  690. }
  691. func (tracker *callTracker) handleDBusError(msg *Message) uint32 {
  692. serial := msg.Headers[FieldReplySerial].value.(uint32)
  693. tracker.lck.RLock()
  694. _, ok := tracker.calls[serial]
  695. tracker.lck.RUnlock()
  696. if ok {
  697. name, _ := msg.Headers[FieldErrorName].value.(string)
  698. tracker.finalizeWithError(serial, Error{name, msg.Body})
  699. }
  700. return serial
  701. }
  702. func (tracker *callTracker) handleSendError(msg *Message, err error) {
  703. if err == nil {
  704. return
  705. }
  706. tracker.lck.RLock()
  707. _, ok := tracker.calls[msg.serial]
  708. tracker.lck.RUnlock()
  709. if ok {
  710. tracker.finalizeWithError(msg.serial, err)
  711. }
  712. }
  713. // finalize was the only func that did not strobe Done
  714. func (tracker *callTracker) finalize(sn uint32) {
  715. tracker.lck.Lock()
  716. defer tracker.lck.Unlock()
  717. c, ok := tracker.calls[sn]
  718. if ok {
  719. delete(tracker.calls, sn)
  720. c.ContextCancel()
  721. }
  722. return
  723. }
  724. func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
  725. tracker.lck.Lock()
  726. c, ok := tracker.calls[sn]
  727. if ok {
  728. delete(tracker.calls, sn)
  729. }
  730. tracker.lck.Unlock()
  731. if ok {
  732. c.Body = body
  733. c.done()
  734. }
  735. return
  736. }
  737. func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
  738. tracker.lck.Lock()
  739. c, ok := tracker.calls[sn]
  740. if ok {
  741. delete(tracker.calls, sn)
  742. }
  743. tracker.lck.Unlock()
  744. if ok {
  745. c.Err = err
  746. c.done()
  747. }
  748. return
  749. }
  750. func (tracker *callTracker) finalizeAllWithError(err error) {
  751. tracker.lck.Lock()
  752. closedCalls := make([]*Call, 0, len(tracker.calls))
  753. for sn := range tracker.calls {
  754. closedCalls = append(closedCalls, tracker.calls[sn])
  755. }
  756. tracker.calls = map[uint32]*Call{}
  757. tracker.lck.Unlock()
  758. for _, call := range closedCalls {
  759. call.Err = err
  760. call.done()
  761. }
  762. }