Better comments, Unlock test.

Add better comments for several functions, fixing errors and clarifying
intent.

Add a test for a lock's Handle and its Unlock method. Clarify that
Unlock is intended to panic if called multiple times after a single
success. Additionally, add implementations for this feature.
diff --git a/fslock/lock.go b/fslock/lock.go
index d29011f..0b96a7c 100644
--- a/fslock/lock.go
+++ b/fslock/lock.go
@@ -13,7 +13,9 @@
 var ErrLockHeld = errors.New("fslock: lock is held")
 
 // Handle is a reference to a held lock. It must be released via Unlock when
-// finished.
+// finished. Multiple calls to Unlock will panic.
+//
+// Handle is NOT safe for concurrent use.
 type Handle interface {
 	// Unlock releases the held lock.
 	//
@@ -23,10 +25,13 @@
 	Unlock() error
 }
 
-// DelayFunc is used for the Delay field in a Lock.
+// Blocker is used for the Delay field in a Lock.
 type Blocker func() error
 
 // L describes a filesystem lock.
+//
+// L's fields should not be modified concurrently, but L's methods are safe
+// for concurrent use.
 type L struct {
 	// Path is the path of the file to lock.
 	Path string
@@ -47,9 +52,10 @@
 	// Block is the configured blocking function.
 	//
 	// If not nil, an attempt to acquire the lock will loop indefinitely until an
-	// error is encountered or the lock is acquired. Block will be called in
-	// between each acquire attempt, and should delay and/or cancel the
-	// acquisition.
+	// error other than ErrLockHeld is encountered (fatal) or the lock is
+	// acquired. Block will be called each time a lock attempt returns
+	// ErrLockHeld, and should delay and/or cancel the acquisition by returning
+	// nil or an error code respectively.
 	//
 	// If Block returns an error, it will be propagated as the error result of the
 	// locking attempt.
diff --git a/fslock/lock_posix.go b/fslock/lock_posix.go
index 6409626..45fb363 100644
--- a/fslock/lock_posix.go
+++ b/fslock/lock_posix.go
@@ -118,6 +118,7 @@
 		return err
 	}
 	delete(l.pls.held, l.ino)
+	l.pls = nil
 	return nil
 }
 
diff --git a/fslock/lock_test.go b/fslock/lock_test.go
index 39f5b44..c48d925 100644
--- a/fslock/lock_test.go
+++ b/fslock/lock_test.go
@@ -368,3 +368,38 @@
 		}
 	})
 }
+
+// TestUnlock tests a lock's Unlock function.
+func TestUnlock(t *testing.T) {
+	t.Parallel()
+
+	withTempDir(t, "content", func(tdir string) {
+		lock := filepath.Join(tdir, "lock")
+		h, err := Lock(lock)
+		if err != nil {
+			t.Fatalf("failed to acquire lock: %v", err)
+		}
+		if h == nil {
+			t.Fatal("lock did not return a Handle")
+		}
+
+		if err := h.Unlock(); err != nil {
+			t.Fatalf("Unlock returned an error: %v", err)
+		}
+
+		var panicVal interface{}
+		err = func() error {
+			defer func() {
+				panicVal = recover()
+			}()
+			return h.Unlock()
+		}()
+		if err != nil {
+			t.Fatalf("second Unlock returned an error: %v", err)
+		}
+		if panicVal == nil {
+			t.Fatal("second Unlock did not panic")
+		}
+		t.Logf("panicked with: %v", panicVal)
+	})
+}
diff --git a/fslock/lock_windows.go b/fslock/lock_windows.go
index eacaef5..1e05ae5 100644
--- a/fslock/lock_windows.go
+++ b/fslock/lock_windows.go
@@ -32,7 +32,16 @@
 	fd *os.File
 }
 
-func (h winLockHandle) Unlock() error { return h.fd.Close() }
+func (h winLockHandle) Unlock() error {
+	if h.fd == nil {
+		panic("lock is not held")
+	}
+	if err := h.fd.Close(); err != nil {
+		return err
+	}
+	h.fd = nil
+	return nil
+}
 
 func exclusiveGetOrCreateFile(path string) (*os.File, bool, error) {
 	mod := syscall.NewLazyDLL("kernel32.dll")