Repository: godbus/dbus (go)

Issue:
Errors with a new connection if previous was closed
In my code I use the following pattern
```
conn, err := dbus.SystemBus()
if err != nil {
	return nil, err
}
defer conn.Close()
```

And in the first function it works great, but the second function fails with error "dbus: connection closed by user". If I remove `defer conn.Close()` the both functions work great.

Pull request description:
Fix singleton can no longer be used after being closed
Fixes #144

Patch:
diff --git a/conn.go b/conn.go
index debe919..29fe018 100644
--- a/conn.go
+++ b/conn.go
@@ -60,7 +60,8 @@ type Conn struct {
 func SessionBus() (conn *Conn, err error) {
 	sessionBusLck.Lock()
 	defer sessionBusLck.Unlock()
-	if sessionBus != nil {
+	if sessionBus != nil &&
+		sessionBus.Connected() {
 		return sessionBus, nil
 	}
 	defer func() {
@@ -105,7 +106,8 @@ func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Co
 func SystemBus() (conn *Conn, err error) {
 	systemBusLck.Lock()
 	defer systemBusLck.Unlock()
-	if systemBus != nil {
+	if systemBus != nil &&
+		systemBus.Connected() {
 		return systemBus, nil
 	}
 	defer func() {
@@ -328,6 +330,11 @@ func (conn *Conn) Context() context.Context {
 	return conn.ctx
 }
 
+// Connected returns whether conn is connected
+func (conn *Conn) Connected() bool {
+	return conn.ctx.Err() == nil
+}
+
 // Eavesdrop causes conn to send all incoming messages to the given channel
 // without further processing. Method replies, errors and signals will not be
 // sent to the appropriate channels and method calls will not be handled. If nil


Test patch:
diff --git a/conn_test.go b/conn_test.go
index 8ac32b8..b73fddd 100644
--- a/conn_test.go
+++ b/conn_test.go
@@ -13,17 +13,43 @@ import (
 )
 
 func TestSessionBus(t *testing.T) {
-	_, err := SessionBus()
+	oldConn, err := SessionBus()
 	if err != nil {
 		t.Error(err)
 	}
+	if err = oldConn.Close(); err != nil {
+		t.Fatal(err)
+	}
+	if oldConn.Connected() {
+		t.Fatal("Should be closed")
+	}
+	newConn, err := SessionBus()
+	if err != nil {
+		t.Error(err)
+	}
+	if newConn == oldConn {
+		t.Fatal("Should get a new connection")
+	}
 }
 
 func TestSystemBus(t *testing.T) {
-	_, err := SystemBus()
+	oldConn, err := SystemBus()
+	if err != nil {
+		t.Error(err)
+	}
+	if err = oldConn.Close(); err != nil {
+		t.Fatal(err)
+	}
+	if oldConn.Connected() {
+		t.Fatal("Should be closed")
+	}
+	newConn, err := SystemBus()
 	if err != nil {
 		t.Error(err)
 	}
+	if newConn == oldConn {
+		t.Fatal("Should get a new connection")
+	}
 }
 
 func TestConnectSessionBus(t *testing.T) {
@@ -34,6 +60,9 @@ func TestConnectSessionBus(t *testing.T) {
 	if err = conn.Close(); err != nil {
 		t.Fatal(err)
 	}
+	if conn.Connected() {
+		t.Fatal("Should be closed")
+	}
 }
 
 func TestConnectSystemBus(t *testing.T) {
@@ -44,6 +73,9 @@ func TestConnectSystemBus(t *testing.T) {
 	if err = conn.Close(); err != nil {
 		t.Fatal(err)
 	}
+	if conn.Connected() {
+		t.Fatal("Should be closed")
+	}
 }
 
 func TestSend(t *testing.T) {