Repository: GoogleCloudPlatform/cloud-bigtable-client (java)

Issue:
If you call BigtableSession.close() more than once you'll get an NPE
java.lang.NullPointerException
[error] 	at com.google.cloud.bigtable.grpc.io.Watchdog.stop(Watchdog.java:122)
[error] 	at com.google.cloud.bigtable.grpc.BigtableSession.close(BigtableSession.java:524)

Watchdog.stop() does the following
```
public void stop() {
    scheduledFuture.cancel(true);
    scheduledFuture = null;
  }
```
BigtableSession.close() calls Watchdog.stop().  If you happen to call close more than once then stop() will cancel and then null out scheduledFuture.  Watchdog.stop() should protect against this by checking if scheduleFuture is already null.


Pull request description:
Fix #2004 - NPE when calling Watchdog.stop() twice

Patch:
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/io/Watchdog.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/io/Watchdog.java
index 8788b258b..cdf8eae36 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/io/Watchdog.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/io/Watchdog.java
@@ -119,8 +119,12 @@ public class Watchdog implements Runnable {
   }
 
   public void stop() {
-    scheduledFuture.cancel(true);
+    ScheduledFuture<?> tmp = scheduledFuture;
     scheduledFuture = null;
+    
+    if (tmp != null) {
+        tmp.cancel(true);
+    }
   }
 
   private class WatchedCall<ReqT, RespT> extends SimpleForwardingClientCall<ReqT, RespT> {


Test patch:
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/io/WatchdogTest.java b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/io/WatchdogTest.java
index 003639df4..77c33d0aa 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/io/WatchdogTest.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/io/WatchdogTest.java
@@ -121,6 +121,12 @@ public class WatchdogTest {
         "Some upstream exception representing cancellation");
   }
 
+  @Test
+  public void testStopTwice() throws Exception {
+    watchdog.stop();
+    watchdog.stop(); // make sure don't get NPE
+  }
+
   static class FakeClientCall extends ClientCall<String, String> {
 
     Listener<String> listener;