Initial cut at an "exported variables" (exvar) package.

This handles integer-valued vars in a singleton struct, and exports functions
for incrementing, setting and getting those vars, as well as rendering all the
vars in a standard format.

Demonstrate the use of the exvar package in the http/triv server.

R=dcross,r
APPROVED=r
DELTA=122  (122 added, 0 deleted, 0 changed)
OCL=27617
CL=27622
diff --git a/src/lib/exvar.go b/src/lib/exvar.go
new file mode 100644
index 0000000..ccfd34a
--- /dev/null
+++ b/src/lib/exvar.go
@@ -0,0 +1,60 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The exvar package provides a standardized interface to public variables,
+// such as operation counters in servers.
+package exvar
+
+import (
+	"fmt";
+	"sync";
+)
+
+// Global state.
+var (
+	mutex sync.Mutex;
+	intVars = make(map[string] int);
+	mapVars = make(map[string] map[string] int);
+	// TODO(dsymonds):
+	// - string-valued vars
+	// - docstrings
+	// - dynamic lookup vars (via chan)
+)
+
+// Increment adds inc to the var called name.
+func Increment(name string, inc int) {
+	mutex.Lock();
+	defer mutex.Unlock();
+
+	if x, ok := intVars[name]; ok {
+		intVars[name] += inc
+	} else {
+		intVars[name] = inc
+	}
+}
+
+// Set sets the var called name to value.
+func Set(name string, value int) {
+	intVars[name] = value
+}
+
+// Get retrieves an integer-valued var called name.
+func Get(name string) (x int, ok bool) {
+	x, ok = intVars[name];
+	return
+}
+
+// TODO(dsymonds): Functions for map-valued vars.
+
+// String produces a string of all the vars in textual format.
+func String() string {
+	mutex.Lock();
+	defer mutex.Unlock();
+
+	s := "";
+	for name, value := range intVars {
+		s += fmt.Sprintln(name, value)
+	}
+	return s
+}