Make it easy to compile-time switch between batched updates or instant update.

This made it easier to figure out where I was feeding it a bad filedescriptor.
Fix the segmentation faults I've been seeing after I implemented persist
events for read and write.

The main problem here - when doing comm_close(), I need to clear the
read/write kqueue events before wrapping up the FD (by calling close())
and also before freeing the event.

Otherwise the kqueue would still have an event in the queue for a now-stale
fde pointer and when it completes, it will lead to a segfault.

The underlying problem:

* with deferred read/write code, there is now a persistent event going on
  even if the read/write is marked as non-active;

* So the close checks in comm.c would assume that it wasn't active, and just
  transition things to closed;

* .. which would schedule an FD read/write event removal, but it wouldn't
  be pushed to the kernel until the queue overflowed or the next IO loop.

NOW:

* if the FD was reused, there would be a stale event entry in the
  list being pushed to the hardware and if yes, the FD is reused,
  adding it will succeed.

* .. So when that (recycled) FD would be read or write ready, you'd
  end up with a note with a stale udata pointer and .. bewm.