func (conn *Conn) inWorker() {
	for {
		msg, err := conn.ReadMessage()
		if err != nil {
			if _, ok := err.(InvalidMessageError); !ok {
				conn.Close()
				conn.calls.finalizeAllWithError(err)
				return
			}
			continue
		}
		conn.eavesdroppedLck.Lock()
		if conn.eavesdropped != nil {
			select {
			case conn.eavesdropped <- msg:
			default:
			}
			conn.eavesdroppedLck.Unlock()
			continue
		}
		conn.eavesdroppedLck.Unlock()
		dest, _ := msg.Headers[FieldDestination].value.(string)
		found := dest == "" ||
			!conn.names.uniqueNameIsKnown() ||
			conn.names.isKnownName(dest)
		if !found {
			continue
		}
		switch msg.Type {
		case TypeError:
			conn.serialGen.retireSerial(conn.calls.handleDBusError(msg))
		case TypeMethodReply:
			conn.serialGen.retireSerial(conn.calls.handleReply(msg))
		case TypeSignal:
			conn.handleSignal(msg)
		case TypeMethodCall:
			go conn.handleCall(msg)
		}
	}
}
inWorker runs in an own goroutine, reading incoming messages from the
transport and dispatching them appropiately.
package dbus
import (
	"context"
	"errors"
	"io"
	"os"
	"reflect"
	"strings"
	"sync"
)
var (
	systemBus     *Conn
	systemBusLck  sync.Mutex
	sessionBus    *Conn
	sessionBusLck sync.Mutex
	sessionEnvLck sync.Mutex
)
var ErrClosed = errors.New("dbus: connection closed by user")
type Conn struct {
	transport
	busObj BusObject
	unixFD bool
	uuid   string
	names *nameTracker
	serialGen *serialGenerator
	calls *callTracker
	handler Handler
	outHandler *outputHandler
	signalHandler SignalHandler
	eavesdropped    chan<- *Message
	eavesdroppedLck sync.Mutex
}
func SessionBus() (conn *Conn, err error) {
	sessionBusLck.Lock()
	defer sessionBusLck.Unlock()
	if sessionBus != nil {
		return sessionBus, nil
	}
	defer func() {
		if conn != nil {
			sessionBus = conn
		}
	}()
	conn, err = SessionBusPrivate()
	if err != nil {
		return
	}
	if err = conn.Auth(nil); err != nil {
		conn.Close()
		conn = nil
		return
	}
	if err = conn.Hello(); err != nil {
		conn.Close()
		conn = nil
	}
	return
}
func getSessionBusAddress() (string, error) {
	sessionEnvLck.Lock()
	defer sessionEnvLck.Unlock()
	address := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
	if address != "" && address != "autolaunch:" {
		return address, nil
	}
	return getSessionBusPlatformAddress()
}
func SessionBusPrivate() (*Conn, error) {
	address, err := getSessionBusAddress()
	if err != nil {
		return nil, err
	}
	return Dial(address)
}
func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
	address, err := getSessionBusAddress()
	if err != nil {
		return nil, err
	}
	return DialHandler(address, handler, signalHandler)
}
func SystemBus() (conn *Conn, err error) {
	systemBusLck.Lock()
	defer systemBusLck.Unlock()
	if systemBus != nil {
		return systemBus, nil
	}
	defer func() {
		if conn != nil {
			systemBus = conn
		}
	}()
	conn, err = SystemBusPrivate()
	if err != nil {
		return
	}
	if err = conn.Auth(nil); err != nil {
		conn.Close()
		conn = nil
		return
	}
	if err = conn.Hello(); err != nil {
		conn.Close()
		conn = nil
	}
	return
}
func SystemBusPrivate() (*Conn, error) {
	return Dial(getSystemBusPlatformAddress())
}
func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
	return DialHandler(getSystemBusPlatformAddress(), handler, signalHandler)
}
func Dial(address string) (*Conn, error) {
	tr, err := getTransport(address)
	if err != nil {
		return nil, err
	}
	return newConn(tr, NewDefaultHandler(), NewDefaultSignalHandler())
}
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
	tr, err := getTransport(address)
	if err != nil {
		return nil, err
	}
	return newConn(tr, handler, signalHandler)
}
func NewConn(conn io.ReadWriteCloser) (*Conn, error) {
	return NewConnHandler(conn, NewDefaultHandler(), NewDefaultSignalHandler())
}
func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
	return newConn(genericTransport{conn}, handler, signalHandler)
}
func newConn(tr transport, handler Handler, signalHandler SignalHandler) (*Conn, error) {
	conn := new(Conn)
	conn.transport = tr
	conn.calls = newCallTracker()
	conn.handler = handler
	conn.signalHandler = signalHandler
	conn.outHandler = &outputHandler{conn: conn}
	conn.serialGen = newSerialGenerator()
	conn.names = newNameTracker()
	conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
	return conn, nil
}
func (conn *Conn) BusObject() BusObject {
	return conn.busObj
}
func (conn *Conn) Close() error {
	conn.outHandler.close()
	if term, ok := conn.signalHandler.(Terminator); ok {
		term.Terminate()
	}
	if term, ok := conn.handler.(Terminator); ok {
		term.Terminate()
	}
	conn.eavesdroppedLck.Lock()
	if conn.eavesdropped != nil {
		close(conn.eavesdropped)
	}
	conn.eavesdroppedLck.Unlock()
	return conn.transport.Close()
}
func (conn *Conn) Eavesdrop(ch chan<- *Message) {
	conn.eavesdroppedLck.Lock()
	conn.eavesdropped = ch
	conn.eavesdroppedLck.Unlock()
}
func (conn *Conn) getSerial() uint32 {
	return conn.serialGen.getSerial()
}
func (conn *Conn) Hello() error {
	var s string
	err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
	if err != nil {
		return err
	}
	conn.names.acquireUniqueConnectionName(s)
	return nil
}