Repository: godbus/dbus
Pull request #209 (2020-07-14 07:04:03)

Mention another project that uses godbus/dbus
This commits add another project to the "Projects using godbus" section in the Readme.md

shibumi: Hi,
I am pretty new to dbus, but I've started a small project that implements go dbus bindings for iwd.
My plan is to have a small wifi-menu like client for iwd, written in Go.

Patch:
diff --git a/README.markdown b/README.markdown
index 26d5fe2..4f69943 100644
--- a/README.markdown
+++ b/README.markdown
@@ -33,6 +33,7 @@ gives a short overview over the basic usage.
 - [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
 - [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API.
 - [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
+- [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd".
 
 Please note that the API is considered unstable for now and may change without
 further notice.
diff --git a/conn.go b/conn.go
index 3507aa6..f959d21 100644
--- a/conn.go
+++ b/conn.go
@@ -586,8 +586,14 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
 // AddMatchSignal registers the given match rule to receive broadcast
 // signals based on their contents.
 func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
+	return conn.AddMatchSignalContext(context.Background(), options...)
+}
+
+// AddMatchSignalContext acts like AddMatchSignal but takes a context.
+func (conn *Conn) AddMatchSignalContext(ctx context.Context, options ...MatchOption) error {
 	options = append([]MatchOption{withMatchType("signal")}, options...)
-	return conn.busObj.Call(
+	return conn.busObj.CallWithContext(
+		ctx,
 		"org.freedesktop.DBus.AddMatch", 0,
 		formatMatchOptions(options),
 	).Store()
@@ -595,8 +601,14 @@ func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
 
 // RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal.
 func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error {
+	return conn.RemoveMatchSignalContext(context.Background(), options...)
+}
+
+// RemoveMatchSignalContext acts like RemoveMatchSignal but takes a context.
+func (conn *Conn) RemoveMatchSignalContext(ctx context.Context, options ...MatchOption) error {
 	options = append([]MatchOption{withMatchType("signal")}, options...)
-	return conn.busObj.Call(
+	return conn.busObj.CallWithContext(
+		ctx,
 		"org.freedesktop.DBus.RemoveMatch", 0,
 		formatMatchOptions(options),
 	).Store()


Test patch:
diff --git a/conn_test.go b/conn_test.go
index 9ab34c7..ff23b71 100644
--- a/conn_test.go
+++ b/conn_test.go
@@ -206,6 +206,69 @@ func TestCloseChannelAfterRemoveSignal(t *testing.T) {
 	close(ch)
 }
 
+func TestAddAndRemoveMatchSignalContext(t *testing.T) {
+	conn, err := ConnectSessionBus()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+
+	sigc := make(chan *Signal, 1)
+	conn.Signal(sigc)
+
+	ctx, cancel := context.WithCancel(context.Background())
+	cancel()
+	// try to subscribe to a made up signal with an already canceled context
+	if err = conn.AddMatchSignalContext(
+		ctx,
+		WithMatchInterface("org.test"),
+		WithMatchMember("CtxTest"),
+	); err == nil {
+		t.Fatal("call on canceled context did not fail")
+	}
+
+	// subscribe to the signal with background context
+	if err = conn.AddMatchSignalContext(
+		context.Background(),
+		WithMatchInterface("org.test"),
+		WithMatchMember("CtxTest"),
+	); err != nil {
+		t.Fatal(err)
+	}
+
+	// try to unsubscribe with an already canceled context
+	if err = conn.RemoveMatchSignalContext(
+		ctx,
+		WithMatchInterface("org.test"),
+		WithMatchMember("CtxTest"),
+	); err == nil {
+		t.Fatal("call on canceled context did not fail")
+	}
+
+	// check that signal is still delivered
+	if err = conn.Emit("/", "org.test.CtxTest"); err != nil {
+		t.Fatal(err)
+	}
+	if sig := waitSignal(sigc, "org.test.CtxTest", time.Second); sig == nil {
+		t.Fatal("signal receive timed out")
+	}
+
+	// unsubscribe from the signal
+	if err = conn.RemoveMatchSignalContext(
+		context.Background(),
+		WithMatchInterface("org.test"),
+		WithMatchMember("CtxTest"),
+	); err != nil {
+		t.Fatal(err)
+	}
+	if err = conn.Emit("/", "org.test.CtxTest"); err != nil {
+		t.Fatal(err)
+	}
+	if sig := waitSignal(sigc, "org.test.CtxTest", time.Second); sig != nil {
+		t.Fatalf("unsubscribed from %q signal, but received %#v", "org.test.CtxTest", sig)
+	}
+}
+
 func TestAddAndRemoveMatchSignal(t *testing.T) {
 	conn, err := ConnectSessionBus()
 	if err != nil {