MySQL Fix

Fixed a latent bug in the MySQL Data Provider, specifically in the Connection::set method -- which sets options on a MYSQL structure before connection.

The only thing that method is currently used for is setting the MYSQL_OPT_RECONNECT option, however the method takes an enum mysql_option parameter, and can therefore -- in theory -- be used to set any option prior to connection.

Due to an oversight, however, the enum mysql_option parameter was ignored, and MYSQL_OPT_RECONNECT was unconditionally passed through to the mysql_options function.

Due to the limited manner in which this function is currently used this caused no problems, as the function behaved as expected, however going forward this could've caused confusion and was not intended.
World Module Maintenance Update

Updated the World module to use the SaveManager for its maintenance cycle, rather than needlessly implementing its own maintenance loop, with associated configuration et cetera.

This also simplified the maintenance code -- the SaveManager panics the server whenever any of its callbacks throw, so there's no need for the World module's maintenance routine to handle this internally.
World Events Fix

I was previously under the impression that C-style arrays -- which the World module uses to store its event handlers -- required manual memory management when used for non-trivial objects.  This is not the case.  Accordingly the code I'd written to perform this manual memory management has been removed.
World Save Compression

Modified the World module's save and load routines to zlib deflate and inflate column data, respectively.  This reduces the amount of data saved in the backing store by about 80x in my tests.

Since communicating with the backing store -- whether a database or directly to disk -- is in most cases the bottleneck, this accelerates that process.  It also keeps the size of the world on disk from getting out of hand, as it was liable to previously.
ClientListIterator Improvements

Added a move constructor and assignment operator to the ClientListIterator class.  This cuts the number of lock operations performed by these iterators approximately in half.

Also added a check for assignment to self in the copy constructor, and centralized/generalized the cleanup code.
Server Uninitialized Pointers Fix

Added initialization for two pointers in the Server class.
Server Shutdown Changes

Cleaned up some shutdown-related code inside the Server class.

Previously it was possible for multiple concurrent shutdown operations to proceed simultaneously, with each one launching a worker thread, attempting to shut the server down, and then all but the first bailing out after discovering the server was already shut down.

Now each successive request to shutdown will see that a shutdown is in process, and bail out immediately, without the overhead of creating a worker thread.

Cleaned up the way in which locking/waiting is handled with respect to the shutdown process.
ClientList Fix

Fixed a race condition in the ClientList class:

Previously, when creating start/end iterators, the ClientList class did not acquire the read lock, leaving that for the ClientListIterator instance it was creating.

However, in invoking the ClientListIterator constructor, the begin or end method (as applicable) of the ClientList's internal std::unordered_set must be invoked to get iterators for the ClientListIterator to wrap.  It was therefore possible for the std::unordered_set to be modified between when these iterators were created and when the ClientListIterator instance acquired the read lock.

Accordingly, the creation of these iterators is now guarded by the read lock.
Windows Network Stack Fix

Fixed a race condition within the Windows network stack:

The Windows network stack uses the MCPP::NetworkImpl::ReferenceManager class internally, to ensure that asynchronous callbacks dispatched due to events on connected sockets do not try and access the ConnectionHandler after it has been destroyed.

Accordingly, the ConnectionHandler destructor waits on the RefereneceManager.

However, there was a race condition -- the ReferenceManager::End method did not properly wake the ReferenceManager's internal condition variable if the count variable reached zero -- and therefore if the ConnectionHandler destructor attempted to wait on the ReferenceManager while a reference was still held by an asynchronous callback, the destructor would be stuck waiting indefinitely.