veyron2/context: Allow users to remove cancellation and deadlines from contexts.

Also remove the previous hack that prevented unmounting from being canceled.

Change-Id: I23ec4f1441de9a0b74f72df80ca84b86f4d000ff
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index c0d41df..5f53bc8 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -296,15 +296,6 @@
 	return
 }
 
-func allowCancel(opts []ipc.CallOpt) bool {
-	for _, o := range opts {
-		if _, ok := o.(inaming.NoCancel); ok {
-			return false
-		}
-	}
-	return true
-}
-
 func mkDischargeImpetus(serverBlessings []string, method string, args []interface{}) security.DischargeImpetus {
 	var impetus security.DischargeImpetus
 	if len(serverBlessings) > 0 {
@@ -500,10 +491,7 @@
 				continue
 			}
 
-			var doneChan <-chan struct{}
-			if allowCancel(opts) {
-				doneChan = ctx.Done()
-			}
+			doneChan := ctx.Done()
 			r.flow.SetDeadline(doneChan)
 
 			var (
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index f9859b2..2db17e4 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -88,7 +88,7 @@
 }
 
 func testContextWithoutDeadline() *context.T {
-	var ctx *context.T
+	ctx, _ := context.RootContext()
 	ctx, err := ivtrace.Init(ctx, flags.VtraceFlags{})
 	if err != nil {
 		panic(err)
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 936402c..7fc7546 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -40,6 +40,7 @@
 	sync.Mutex
 	state        serverState          // track state of the server.
 	ctx          *context.T           // context used by the server to make internal RPCs.
+	cancel       context.CancelFunc   // function to cancel the above context.
 	streamMgr    stream.Manager       // stream manager to listen for new flows.
 	publisher    publisher.Publisher  // publisher to publish mounttable mounts.
 	listenerOpts []stream.ListenerOpt // listener opts for Listen.
@@ -147,10 +148,12 @@
 func (ReservedNameDispatcher) IPCServerOpt() {}
 
 func InternalNewServer(ctx *context.T, streamMgr stream.Manager, ns naming.Namespace, client ipc.Client, opts ...ipc.ServerOpt) (ipc.Server, error) {
+	ctx, cancel := context.WithRootCancel(ctx)
 	ctx, _ = vtrace.SetNewSpan(ctx, "NewServer")
 	statsPrefix := naming.Join("ipc", "server", "routing-id", streamMgr.RoutingID().String())
 	s := &server{
 		ctx:           ctx,
+		cancel:        cancel,
 		streamMgr:     streamMgr,
 		publisher:     publisher.New(ctx, ns, publishPeriod),
 		listeners:     make(map[stream.Listener]struct{}),
@@ -842,6 +845,7 @@
 		return verror.Make(verror.Internal, s.ctx, firstErr)
 	}
 	s.state = stopped
+	s.cancel()
 	return nil
 }
 
diff --git a/runtimes/google/lib/publisher/publisher_test.go b/runtimes/google/lib/publisher/publisher_test.go
index 1fe0992..a70d1e2 100644
--- a/runtimes/google/lib/publisher/publisher_test.go
+++ b/runtimes/google/lib/publisher/publisher_test.go
@@ -23,7 +23,7 @@
 }
 
 func testContext() *context.T {
-	var ctx *context.T
+	ctx, _ := context.RootContext()
 	ctx, err := ivtrace.Init(ctx, flags.VtraceFlags{})
 	if err != nil {
 		panic(err)
diff --git a/runtimes/google/naming/namespace/mount.go b/runtimes/google/naming/namespace/mount.go
index 7b7ce3a..0cab494 100644
--- a/runtimes/google/naming/namespace/mount.go
+++ b/runtimes/google/naming/namespace/mount.go
@@ -37,7 +37,7 @@
 func unmountFromMountTable(ctx *context.T, client ipc.Client, name, server string, id string) (s status) {
 	s.id = id
 	ctx, _ = context.WithTimeout(ctx, callTimeout)
-	call, err := client.StartCall(ctx, name, "Unmount", []interface{}{server}, options.NoResolve{}, inaming.NoCancel{})
+	call, err := client.StartCall(ctx, name, "Unmount", []interface{}{server}, options.NoResolve{})
 	s.err = err
 	if err != nil {
 		return
@@ -139,7 +139,7 @@
 	f := func(context *context.T, mt, id string) status {
 		return unmountFromMountTable(ctx, client, mt, server, id)
 	}
-	err := ns.dispatch(ctx, name, f, inaming.NoCancel{})
+	err := ns.dispatch(ctx, name, f)
 	vlog.VI(1).Infof("Unmount(%s, %s) -> %v", name, server, err)
 	return err
 }
diff --git a/runtimes/google/naming/nocancel.go b/runtimes/google/naming/nocancel.go
deleted file mode 100644
index 85e1658..0000000
--- a/runtimes/google/naming/nocancel.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package naming
-
-// NoCancel is an option passed to a resolve or an IPC call that
-// instructs it to ignore cancellation for that call.
-// This is used to allow servers to unmount even after their context
-// has been cancelled.
-// TODO(mattr): Find a better mechanism for this.
-type NoCancel struct{}
-
-func (NoCancel) IPCCallOpt()   {}
-func (NoCancel) NSResolveOpt() {}
diff --git a/runtimes/google/rt/runtime_test.go b/runtimes/google/rt/runtime_test.go
index 4f41e20..5d1beaf 100644
--- a/runtimes/google/rt/runtime_test.go
+++ b/runtimes/google/rt/runtime_test.go
@@ -14,7 +14,7 @@
 
 // InitForTest creates a context for use in a test.
 func InitForTest(t *testing.T) (*rt.Runtime, *context.T, veyron2.Shutdown) {
-	ctx, cancel := context.WithCancel(nil)
+	ctx, cancel := context.RootContext()
 	r, ctx, shutdown, err := rt.Init(ctx, nil, nil, nil, flags.RuntimeFlags{}, nil)
 	if err != nil {
 		t.Fatal(err)
diff --git a/runtimes/google/testing/mocks/ipc/simple_client_test.go b/runtimes/google/testing/mocks/ipc/simple_client_test.go
index a4bd4f0..f14eb7d 100644
--- a/runtimes/google/testing/mocks/ipc/simple_client_test.go
+++ b/runtimes/google/testing/mocks/ipc/simple_client_test.go
@@ -7,11 +7,8 @@
 )
 
 func testContext() *context.T {
-	// The nil context is not directly usable, we need to create
-	// a context specially.
-	type key struct{}
-	var ctx *context.T
-	return context.WithValue(ctx, key{}, nil)
+	ctx, _ := context.RootContext()
+	return ctx
 }
 
 func TestSuccessfulCalls(t *testing.T) {