default_handler.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package dbus
  2. import (
  3. "bytes"
  4. "reflect"
  5. "strings"
  6. "sync"
  7. )
  8. func newIntrospectIntf(h *defaultHandler) *exportedIntf {
  9. methods := make(map[string]Method)
  10. methods["Introspect"] = exportedMethod{
  11. reflect.ValueOf(func(msg Message) (string, *Error) {
  12. path := msg.Headers[FieldPath].value.(ObjectPath)
  13. return h.introspectPath(path), nil
  14. }),
  15. }
  16. return newExportedIntf(methods, true)
  17. }
  18. //NewDefaultHandler returns an instance of the default
  19. //call handler. This is useful if you want to implement only
  20. //one of the two handlers but not both.
  21. //
  22. // Deprecated: this is the default value, don't use it, it will be unexported.
  23. func NewDefaultHandler() *defaultHandler {
  24. h := &defaultHandler{
  25. objects: make(map[ObjectPath]*exportedObj),
  26. defaultIntf: make(map[string]*exportedIntf),
  27. }
  28. h.defaultIntf["org.freedesktop.DBus.Introspectable"] = newIntrospectIntf(h)
  29. return h
  30. }
  31. type defaultHandler struct {
  32. sync.RWMutex
  33. objects map[ObjectPath]*exportedObj
  34. defaultIntf map[string]*exportedIntf
  35. }
  36. func (h *defaultHandler) PathExists(path ObjectPath) bool {
  37. _, ok := h.objects[path]
  38. return ok
  39. }
  40. func (h *defaultHandler) introspectPath(path ObjectPath) string {
  41. subpath := make(map[string]struct{})
  42. var xml bytes.Buffer
  43. xml.WriteString("<node>")
  44. for obj := range h.objects {
  45. p := string(path)
  46. if p != "/" {
  47. p += "/"
  48. }
  49. if strings.HasPrefix(string(obj), p) {
  50. node_name := strings.Split(string(obj[len(p):]), "/")[0]
  51. subpath[node_name] = struct{}{}
  52. }
  53. }
  54. for s := range subpath {
  55. xml.WriteString("\n\t<node name=\"" + s + "\"/>")
  56. }
  57. xml.WriteString("\n</node>")
  58. return xml.String()
  59. }
  60. func (h *defaultHandler) LookupObject(path ObjectPath) (ServerObject, bool) {
  61. h.RLock()
  62. defer h.RUnlock()
  63. object, ok := h.objects[path]
  64. if ok {
  65. return object, ok
  66. }
  67. // If an object wasn't found for this exact path,
  68. // look for a matching subtree registration
  69. subtreeObject := newExportedObject()
  70. path = path[:strings.LastIndex(string(path), "/")]
  71. for len(path) > 0 {
  72. object, ok = h.objects[path]
  73. if ok {
  74. for name, iface := range object.interfaces {
  75. // Only include this handler if it registered for the subtree
  76. if iface.isFallbackInterface() {
  77. subtreeObject.interfaces[name] = iface
  78. }
  79. }
  80. break
  81. }
  82. path = path[:strings.LastIndex(string(path), "/")]
  83. }
  84. for name, intf := range h.defaultIntf {
  85. if _, exists := subtreeObject.interfaces[name]; exists {
  86. continue
  87. }
  88. subtreeObject.interfaces[name] = intf
  89. }
  90. return subtreeObject, true
  91. }
  92. func (h *defaultHandler) AddObject(path ObjectPath, object *exportedObj) {
  93. h.Lock()
  94. h.objects[path] = object
  95. h.Unlock()
  96. }
  97. func (h *defaultHandler) DeleteObject(path ObjectPath) {
  98. h.Lock()
  99. delete(h.objects, path)
  100. h.Unlock()
  101. }
  102. type exportedMethod struct {
  103. reflect.Value
  104. }
  105. func (m exportedMethod) Call(args ...interface{}) ([]interface{}, error) {
  106. t := m.Type()
  107. params := make([]reflect.Value, len(args))
  108. for i := 0; i < len(args); i++ {
  109. params[i] = reflect.ValueOf(args[i]).Elem()
  110. }
  111. ret := m.Value.Call(params)
  112. var err error
  113. nilErr := false // The reflection will find almost-nils, let's only pass back clean ones!
  114. if t.NumOut() > 0 {
  115. if e, ok := ret[t.NumOut()-1].Interface().(*Error); ok { // godbus *Error
  116. nilErr = ret[t.NumOut()-1].IsNil()
  117. ret = ret[:t.NumOut()-1]
  118. err = e
  119. } else if ret[t.NumOut()-1].Type().Implements(errType) { // Go error
  120. i := ret[t.NumOut()-1].Interface()
  121. if i == nil {
  122. nilErr = ret[t.NumOut()-1].IsNil()
  123. } else {
  124. err = i.(error)
  125. }
  126. ret = ret[:t.NumOut()-1]
  127. }
  128. }
  129. out := make([]interface{}, len(ret))
  130. for i, val := range ret {
  131. out[i] = val.Interface()
  132. }
  133. if nilErr || err == nil {
  134. //concrete type to interface nil is a special case
  135. return out, nil
  136. }
  137. return out, err
  138. }
  139. func (m exportedMethod) NumArguments() int {
  140. return m.Value.Type().NumIn()
  141. }
  142. func (m exportedMethod) ArgumentValue(i int) interface{} {
  143. return reflect.Zero(m.Type().In(i)).Interface()
  144. }
  145. func (m exportedMethod) NumReturns() int {
  146. return m.Value.Type().NumOut()
  147. }
  148. func (m exportedMethod) ReturnValue(i int) interface{} {
  149. return reflect.Zero(m.Type().Out(i)).Interface()
  150. }
  151. func newExportedObject() *exportedObj {
  152. return &exportedObj{
  153. interfaces: make(map[string]*exportedIntf),
  154. }
  155. }
  156. type exportedObj struct {
  157. mu sync.RWMutex
  158. interfaces map[string]*exportedIntf
  159. }
  160. func (obj *exportedObj) LookupInterface(name string) (Interface, bool) {
  161. if name == "" {
  162. return obj, true
  163. }
  164. obj.mu.RLock()
  165. defer obj.mu.RUnlock()
  166. intf, exists := obj.interfaces[name]
  167. return intf, exists
  168. }
  169. func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) {
  170. obj.mu.Lock()
  171. defer obj.mu.Unlock()
  172. obj.interfaces[name] = iface
  173. }
  174. func (obj *exportedObj) DeleteInterface(name string) {
  175. obj.mu.Lock()
  176. defer obj.mu.Unlock()
  177. delete(obj.interfaces, name)
  178. }
  179. func (obj *exportedObj) LookupMethod(name string) (Method, bool) {
  180. obj.mu.RLock()
  181. defer obj.mu.RUnlock()
  182. for _, intf := range obj.interfaces {
  183. method, exists := intf.LookupMethod(name)
  184. if exists {
  185. return method, exists
  186. }
  187. }
  188. return nil, false
  189. }
  190. func (obj *exportedObj) isFallbackInterface() bool {
  191. return false
  192. }
  193. func newExportedIntf(methods map[string]Method, includeSubtree bool) *exportedIntf {
  194. return &exportedIntf{
  195. methods: methods,
  196. includeSubtree: includeSubtree,
  197. }
  198. }
  199. type exportedIntf struct {
  200. methods map[string]Method
  201. // Whether or not this export is for the entire subtree
  202. includeSubtree bool
  203. }
  204. func (obj *exportedIntf) LookupMethod(name string) (Method, bool) {
  205. out, exists := obj.methods[name]
  206. return out, exists
  207. }
  208. func (obj *exportedIntf) isFallbackInterface() bool {
  209. return obj.includeSubtree
  210. }
  211. //NewDefaultSignalHandler returns an instance of the default
  212. //signal handler. This is useful if you want to implement only
  213. //one of the two handlers but not both.
  214. //
  215. // Deprecated: this is the default value, don't use it, it will be unexported.
  216. func NewDefaultSignalHandler() *defaultSignalHandler {
  217. return &defaultSignalHandler{}
  218. }
  219. type defaultSignalHandler struct {
  220. mu sync.RWMutex
  221. closed bool
  222. signals []*signalChannelData
  223. }
  224. func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
  225. sh.mu.RLock()
  226. defer sh.mu.RUnlock()
  227. if sh.closed {
  228. return
  229. }
  230. for _, scd := range sh.signals {
  231. scd.deliver(signal)
  232. }
  233. }
  234. func (sh *defaultSignalHandler) Terminate() {
  235. sh.mu.Lock()
  236. defer sh.mu.Unlock()
  237. if sh.closed {
  238. return
  239. }
  240. for _, scd := range sh.signals {
  241. scd.close()
  242. close(scd.ch)
  243. }
  244. sh.closed = true
  245. sh.signals = nil
  246. }
  247. func (sh *defaultSignalHandler) AddSignal(ch chan<- *Signal) {
  248. sh.mu.Lock()
  249. defer sh.mu.Unlock()
  250. if sh.closed {
  251. return
  252. }
  253. sh.signals = append(sh.signals, &signalChannelData{
  254. ch: ch,
  255. done: make(chan struct{}),
  256. })
  257. }
  258. func (sh *defaultSignalHandler) RemoveSignal(ch chan<- *Signal) {
  259. sh.mu.Lock()
  260. defer sh.mu.Unlock()
  261. if sh.closed {
  262. return
  263. }
  264. for i := len(sh.signals) - 1; i >= 0; i-- {
  265. if ch == sh.signals[i].ch {
  266. sh.signals[i].close()
  267. copy(sh.signals[i:], sh.signals[i+1:])
  268. sh.signals[len(sh.signals)-1] = nil
  269. sh.signals = sh.signals[:len(sh.signals)-1]
  270. }
  271. }
  272. }
  273. type signalChannelData struct {
  274. wg sync.WaitGroup
  275. ch chan<- *Signal
  276. done chan struct{}
  277. }
  278. func (scd *signalChannelData) deliver(signal *Signal) {
  279. select {
  280. case scd.ch <- signal:
  281. case <-scd.done:
  282. return
  283. default:
  284. scd.wg.Add(1)
  285. go scd.deferredDeliver(signal)
  286. }
  287. }
  288. func (scd *signalChannelData) deferredDeliver(signal *Signal) {
  289. select {
  290. case scd.ch <- signal:
  291. case <-scd.done:
  292. }
  293. scd.wg.Done()
  294. }
  295. func (scd *signalChannelData) close() {
  296. close(scd.done)
  297. scd.wg.Wait() // wait until all spawned goroutines return
  298. }