WIP: Use per-agent locks instead of a global lock
This is a port on master of the originally proposed fix for the long standing #1 (closed) issue. At the moment, this is exactly the same patch @nifigase submitted at the time, so I don't claim any authorship on it: I just submitted it as it was not migrated here when libnice was moved to GitLab. The plan is to try and complete the work myself, sooner or later, considering @nifigase didn't return to the comments made a few months ago and so may or may not available for that.
I realize @ocrete had some concerns on the current state of the patch, so I'll manually add his original review comments in here as well so that we can keep on discussing them within this context. While some seemed easier to address than others, I'm admittedly not an expert on the libnice or glib internals, so I'd welcome any guidance to fix what still remains to be fixed and finally merge this.
Just as a side note, we tested this extensively in some internal stress test campaigns at Meetecho, and could confirm the huge performance boost it provided us with. We didn't experience any crash or weird behaviour, even though we're obviously not representative of the whole spectrum of applications libnice can support, and so this may not be true for different use cases. At any rate, the tests were made with ICE Full enabled, involved libnice acting both as controller and controlled, and didn't involve TURN or TCP. If you're interested in more details on that part, please feel free to ask.