Otherwise we prematurely release the goroutine from the os thread resulting in a crash, as the GIL locking mechanisms allow reentrance.
We want to keep these indirections, which means that the Go runtime needs to know that we are holding references to them. It won't look at the contexts structs, because they are C types and so opaque to the runtime - so we need to store them separately in a way the runtime will see them.
Go 1.1 has changed the way that functions work - basically, we have to point at a pointer to the actual code. Since we don't really want to maintain different versions of the code for 1.0 & 1.1 - we use runtime detection to figure out whether the indirection is needed.
Some of the locks recently introduced make more sense as RWMutex than as Mutex. They are all protecting state that is likely to be accessed a lot more than it is modified. There is no need to serialise accesses, only to make sure that there is no access in parallel with a modify - which is exactly the protection a RWMutex gives us.
There are some global variables that are used to maintain global state. These variables need to be protected if we are going to be accessing them from multiple goroutines (which we may well be). Not all of the variables are locked by this change. Hopefully those that aren't have at least got a TODO now though ...