diff --git a/conn_test.go b/conn_test.go index d93527b6..1742cbf6 100644 --- a/conn_test.go +++ b/conn_test.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "testing" + "time" ) func TestSessionBus(t *testing.T) { @@ -44,6 +45,23 @@ func TestSend(t *testing.T) { } } +func TestFlagNoReplyExpectedSend(t *testing.T) { + bus, err := SessionBus() + if err != nil { + t.Fatal(err) + } + done := make(chan struct{}) + go func() { + bus.BusObject().Call("org.freedesktop.DBus.ListNames", FlagNoReplyExpected) + close(done) + }() + select { + case <-done: + case <-time.After(1 * time.Second): + t.Error("Failed to announce that the call was done") + } +} + func TestRemoveSignal(t *testing.T) { bus, err := NewConn(nil) if err != nil { diff --git a/object.go b/object.go index 33367253..6d95583d 100644 --- a/object.go +++ b/object.go @@ -43,7 +43,8 @@ func (o *Object) AddMatchSignal(iface, member string) *Call { // will be allocated. Otherwise, ch has to be buffered or Go will panic. // // If the flags include FlagNoReplyExpected, ch is ignored and a Call structure -// is returned of which only the Err member is valid. +// is returned with any error in Err and a closed channel in Done containing +// the returned Call as it's one entry. // // If the method parameter contains a dot ('.'), the part before the last dot // specifies the interface on which the method is called. @@ -97,11 +98,21 @@ func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface } o.conn.outLck.RLock() defer o.conn.outLck.RUnlock() + done := make(chan *Call, 1) + call := &Call{ + Err: nil, + Done: done, + } + defer func() { + call.Done <- call + close(done) + }() if o.conn.closed { - return &Call{Err: ErrClosed} + call.Err = ErrClosed + return call } o.conn.out <- msg - return &Call{Err: nil} + return call } // GetProperty calls org.freedesktop.DBus.Properties.GetProperty on the given