private void GetConfig()
		{
			config = ConfigurationManager.GetSection(_configSectionName) as SocketServerConfig;

			if (config == null)
			{
				if (log.IsWarnEnabled)
					log.Warn("No Socket Server Config Found. Using defaults.");
				config = new SocketServerConfig();
			}

			useNetworkOrder = config.UseNetworkOrder;

			initialMessageSize = config.InitialMessageSize;
			maximumMessageSize = config.MaximumMessageSize;
			discardTooBigMessages = config.DiscardTooBigMessages;
			maximumSockets = (config.MaximumOpenSockets == 0 ? Int32.MaxValue : config.MaximumOpenSockets);
			if (log.IsInfoEnabled)
			{
				log.InfoFormat("Maximum Message size is {0}. {1}.", maximumMessageSize.ToString("N0"),
					 (discardTooBigMessages) ? "Discarding too big messages" : "Immediately disposing too big message buffers");
			}

			if (config.SyncThreads > 0)
			{
				SyncThreads = config.SyncThreads;
			}
			else
			{
				SyncThreads = Environment.ProcessorCount * Dispatcher.ThreadsPerCpu;
			}

			if (config.OnewayThreads > 0)
			{
				OnewayThreads = config.OnewayThreads;
			}
			else
			{
				OnewayThreads = Environment.ProcessorCount * Dispatcher.ThreadsPerCpu;
			}

			XmlSerializerSectionHandler.RegisterReloadNotification(typeof(SocketServerConfig), new EventHandler(ReloadConfig));
		}
		public void ReloadConfig(object sender, EventArgs args)
		{
			if (log.IsInfoEnabled)
				log.Info("Reloading config");
			connectionWatcher.Change(Timeout.Infinite, Timeout.Infinite);
			SocketServerConfig newConfig = ConfigurationManager.GetSection(_configSectionName) as SocketServerConfig;
			if (newConfig == null)
			{
				if (log.IsWarnEnabled)
					log.Warn("No Socket Server Config Found. Using defaults.");
				newConfig = new SocketServerConfig();
			}
			maximumMessageSize = newConfig.MaximumMessageSize;
			discardTooBigMessages = newConfig.DiscardTooBigMessages;
			connectionCheckInterval = newConfig.ConnectionCheckIntervalSeconds;
			useNetworkOrder = newConfig.UseNetworkOrder;
			maximumSockets = (newConfig.MaximumOpenSockets == 0 ? Int32.MaxValue : newConfig.MaximumOpenSockets);
			int bufferInitMsgSize = newConfig.InitialMessageSize;
			int bufferPoolReuses = newConfig.BufferPoolReuses;
			int connectionStateReuses = newConfig.ConnectionStateReuses;

			int currentWorker, currentCompletion, oldWorker, oldCompletion;
			ThreadPool.GetAvailableThreads(out currentWorker, out currentCompletion);
			oldWorker = currentWorker;
			oldCompletion = currentCompletion;
			if (config.MaximumWorkerThreads > 0) currentWorker = config.MaximumWorkerThreads;
			if (config.MaximumCompletionPortThreads > 0) currentCompletion = config.MaximumCompletionPortThreads;
			bool maxSet = ThreadPool.SetMaxThreads(currentWorker, currentCompletion);
			
			if (config.MaximumWorkerThreads > 0 || config.MaximumCompletionPortThreads > 0)
			{
				if (maxSet == false)
				{
					if (log.IsWarnEnabled)
					{
						log.WarnFormat("FAILED to change max ThreadPool threads from ({0}worker/{1}completion) to ({2}worker/{3}completion)", oldWorker, oldCompletion, currentWorker, currentCompletion);
					}
				}
				else
				{
					if (log.IsInfoEnabled) log.InfoFormat("Successfully changed max ThreadPool threads from ({0}worker/{1}completion) to ({2}worker/{3}completion)", oldWorker, oldCompletion, currentWorker, currentCompletion);
				}
			}

			Interlocked.Exchange(ref connectionCheckInterval, newConfig.ConnectionCheckIntervalSeconds * 1000);

			if (log.IsInfoEnabled)
			{
				log.InfoFormat("Setting default msg size to {0}. Setting connection check interval to {1} ms.", bufferInitMsgSize, connectionCheckInterval);
				log.InfoFormat("Maximum Message size is {0}. {1}.", maximumMessageSize.ToString("N0"),
					 (discardTooBigMessages) ? "Discarding too big messages" : "Immediately disposing too big message buffers");
			}
			bufferPool.InitialBufferSize = bufferInitMsgSize;
			bufferPool.BufferReuses = bufferPoolReuses;
			connectionStatePool.MaxItemReuses = connectionStateReuses;

			connectionWatcher.Change(connectionCheckInterval, connectionCheckInterval);

			int newOnewayThreads =
				(newConfig.OnewayThreads == 0 ? (Environment.ProcessorCount * Dispatcher.ThreadsPerCpu) : newConfig.OnewayThreads);
			if (newOnewayThreads != OnewayThreads)
			{
				try
				{
					if (log.IsInfoEnabled)
						log.InfoFormat("Changing number of oneway threads from {0} to {1}.", OnewayThreads, newOnewayThreads);
					Dispatcher oldOnewayDispatcher = OnewayDispatcher;
					DispatcherQueue oldOnewayQueue = OnewayMessageQueue;
					Dispatcher newOnewayDispatcher = new Dispatcher(newOnewayThreads, ThreadPriority.Normal, true, "Socket Server OneWay:" + portNumber.ToString());
					DispatcherQueue newOnewayQueue = new DispatcherQueue("Socket Server " + portNumber.ToString() + " one way", newOnewayDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, newConfig.OnewayQueueDepth);

					Interlocked.Exchange<Port<ProcessState>>(ref OnewayMessagePort, new Port<ProcessState>());

					Arbiter.Activate(newOnewayQueue,
						Arbiter.Receive<ProcessState>(true,
						OnewayMessagePort, delegate(ProcessState state) { ProcessCall(state); }));

					OnewayMessageQueue = newOnewayQueue;
					OnewayDispatcher = newOnewayDispatcher;
					oldOnewayDispatcher.Dispose();
					OnewayThreads = newOnewayThreads;
				}
				catch (Exception ex)
				{
					if (log.IsErrorEnabled)
						log.ErrorFormat("Socket Server Exception changing number of sync threads: {0}", ex);
				}
			}

			int newSyncThreads = (newConfig.SyncThreads == 0 ?
				(Environment.ProcessorCount * Dispatcher.ThreadsPerCpu) : newConfig.SyncThreads);

			if (newSyncThreads != SyncThreads)
			{
				try
				{
					if (log.IsInfoEnabled)
						log.InfoFormat("Changing number of sync threads from {0} to {1}", SyncThreads, newSyncThreads);
					Dispatcher oldSyncDispatcher = SyncDispatcher;
					DispatcherQueue oldSyncQueue = SyncMessageQueue;
					Dispatcher newSyncDispatcher = new Dispatcher(newSyncThreads, ThreadPriority.AboveNormal, true, "Socket Server OneWay:" + portNumber.ToString());
					DispatcherQueue newSyncQueue = new DispatcherQueue("Socket Server " + portNumber.ToString() + " one way", newSyncDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, newConfig.SyncQueueDepth);

					Interlocked.Exchange<Port<ProcessState>>(ref SyncMessagePort, new Port<ProcessState>());

					Arbiter.Activate(newSyncQueue,
						Arbiter.Receive<ProcessState>(true,
						SyncMessagePort, delegate(ProcessState state) { ProcessCall(state); }));
					SyncMessageQueue = newSyncQueue;
					SyncDispatcher = newSyncDispatcher;
					oldSyncDispatcher.Dispose();
					SyncThreads = newSyncThreads;
				}
				catch (Exception ex)
				{
					if (log.IsErrorEnabled)
						log.ErrorFormat("Socket Server Exception changing number of sync threads: {0}", ex);
				}
			}

			if (OnewayMessageQueue != null)
			{
				OnewayMessageQueue.MaximumQueueDepth = newConfig.OnewayQueueDepth;
			}
			if (SyncMessageQueue != null)
			{
				SyncMessageQueue.MaximumQueueDepth = newConfig.SyncQueueDepth;
			}

			config = newConfig;
		}