Simplify/fix locking

This makes the locking simpler, and fixes some issues:

1. The ```nextContextId``` generation and the dictionary update in ```addBlock``` needs to be atomic (i.e. within a single locked section), to prevent races.

2. Lock/unlock calls need to happen strictly in matched pairs, which the ```OSSpinLockUnlock(&_fullLock)``` call in ```gotReply``` violates.  If the ```_callbacks``` dictionary is full then we're using way more than 32GB memory just storing callbacks, which doesn't really seem worth considering, so I've removed ```_fullLock``` rather than trying to make it work.  An appropriate way to do this properly might be to use [condition variables](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW4).