New implementation of file locking using flock()

Previous file-locking code was using fcntl locks, which have more
precise and standard semantics for Unix, however they aren't available
on Windows.  Normal lock-files (where existence of the file denotes a
held lock) have a cleanup problem where a process could have an
exception or otherwise forget to clean the lock, and the considerations
about how to handle stale locks.  flock() suffers from the problem where
child processes inherit the lock, and in our case, we don't want the
lock to ever be inherited.  However, if we combine flock() with a
CLOEXEC flag, then a child process can't inherit the file, thus can't
inherit the lock.  (though it doesn't protect against a forked child
that hasn't exec'd, but this is less of a concern)

The lock is no longer package-global, and is now just a file handle ref,
which we store in the field "->_lock_object".  The lock doesn't actually
need to live longer than a single function call, but this preserves the
API.  The next commit will simplify it all at the expense of changing
the API.