Latest release of licensed socket server code: 6.1

The latest release of The Server Framework is now available. This release includes the following changes.

The following changes were made to the libraries.

Admin Library - 6.1

  • We now suppress warning 4370, ’layout of class has changed from a previous version of the compiler due to better packing’, in Warnings.h.

  • New build configuration options. All of these are enabled by defining the option to 1 in Config.h and disabled by defining them to 0; the default state if you do not do anything in Config.h is shown for each option:

  • JETBYTE_TRANSLATE_SEH_EXCEPTIONS - enabled by default. When enabled each thread that is created within the libraries may contain a structured exception translator which will translate Windows structured exceptions into instances of JetByteTools::Win32::CSEHException which can be caught in a normal C++ exception handler. See here http://www.lenholgate.com/archives/000852.html for more details.

  • JETBYTE_TRANSLATE_SEH_EXCEPTIONS_IN_DEBUGGER - enabled by default. If disabled then structured exception transaltion that is controlled by JETBYTE_TRANSLATE_SEH_EXCEPTIONS will not occur if the code is running under a debugger.

  • JETBYTE_CATCH_UNHANDLED_EXCEPTIONS_IN_DESTRUCTORS - enabled by default. Some destructors have catch(...) handlers present to prevent exceptions leaking from them. When disabled all catch(...) handlers in destructors are removed from library code.

  • JETBYTE_CATCH_UNHANDLED_EXCEPTIONS_AT_THREAD_BOUNDARY - enabled by default. Most threads that the libraries create have catch(...) handlers present to prevent exceptions leaking from them. When disabled all catch(...) handlers in threads are removed from library code.

  • JETBYTE_CATCH_UNHANDLED_EXCEPTIONS_IN_NOTHROW_FUNCTIONS - enabled by default. Most functions that are marked with a ’no throw’ (throw()) exception specification to indicate that the function does not throw exceptions also contain a catch(...) handler to ensure that they don’t. When disabled all catch(...) handlers in ’nothrow’ functions are removed from library code.

  • JETBYTE_CATCH_UNHANDLED_EXCEPTIONS - enabled by default. When disabled all catch(...) handlers that haven’t been explicitly enabled by one of the three settings above are removed from the code. See here: http://www.lenholgate.com/archives/000854.html for more details.

  • JETBYTE_EXCEPTION_STACK_TRACES - disabled by default. Enable to capture the stack trace when an exception derived from JetByteTools::Win32::CException is thrown. Enables the use of JetByteTools::Win32::CException::GetCallStack() to report the call stack at the point of the exception.

  • JETBYTE_EXCEPTION_WHERE_INCLUDES_STACK_TRACE - disabled by default. Only valid if JETBYTE_EXCEPTION_STACK_TRACES is defined to 1. Causes JetByteTools::Win32::CException::Where() to also return the call stack of where the exception was thrown.

  • JETBYTE_TRACK_IO_BUFFER_REFERENCES - disabled by default. Enable to track where JetByteTools::IO::CBuffer::AddRef() and JetByteTools::IO::CBuffer::Release() are called from for all instances of JetByteTools::IO::CBuffer. If a buffer is over released (i.e. release is called on a buffer where the reference count is currently zero) then a trace of all calls to JetByteTools::IO::CBuffer::AddRef() and JetByteTools::IO::CBuffer::Release() will be printed to the debug trace output. If a buffer is destroyed and the reference count is not zero then a trace is also printed. Note that there is a considerable run-time cost for this functionality.

  • JETBYTE_TRACK_SOCKET_REFERENCES - disabled by default. Enable to track where JetByteTools::Socket::TAsyncSocket<T>::AddRef() and JetByteTools::Socket::TAsyncSocket<T>::Release() are called from for instances of JetByteTools::Socket::TAsyncSocket derived classes. If a socket is over released (i.e. release is called on a socket where the reference count is currently zero) then a trace of all calls to JetByteTools::Socket::TAsyncSocket<T>::AddRef() and JetByteTools::Socket::TAsyncSocket<T>::Release() will be printed to the debug trace output. If a socket is destroyed and the reference count is not zero then a trace is also printed. Note that there is a considerable run-time performance cost for this functionality.

  • JETBYTE_REFERENCE_TRACKING_DISPLAY_LOADED_PDBS - disabled by default. Enable to display a list of the pdb files that were loaded to provide the callstacks uses by the socket reference tracker, the buffer reference tracker and the exception call stack code.

  • JETBYTE_REFERENCE_COUNTED_SMART_POINTER_THROW_ON_NULL_REFERENCE - disabled by default. Enable to throw exceptions from JetByteTools::Win32::TReferenceCountedSmartPointer<T>::GetRef() if the reference is null. Normally we simply return the null reference and the calling code goes boom…

  • JETBYTE_DISABLE_VS2005_DEBUG_UUIDLIB_CHECK - disabled by default. Enable to turn off the fatal build error in projects that require uuid.lib and that are being built in debug mode using VS2005 with the Windows SDK version v7.0. Some example servers require uuid.lib and the version supplied with the Windows SDK v7.0 contains some debug information that the VS2005 linker can’t understand. These projects include CheckVS2005DebugUuidlibVersion.h which has a go at checking to see if you’re using the Windows SDK v7.0 and if so produces an error message. If you enable this configuration setting the error message becomes a warning and, in all likelyhood, the build will instead fail at the link stage.

Win32 Tools Library - 6.1

  • Added JetByteTools::Win32::CCallStack which is used to represent a call stack within a process.

  • Added JetByteTools::Win32::CCallTracker which is used to collect call stacks for a series of calls to a function.

  • Added JetByteTools::Win32::IAllocateFixedSizeMemory and JetByteTools::Win32::CSimpleFixedSizedMemoryAllocator which provides a nieve fixed sized memory allocator.

  • Added JetByteTools::Win32::ITrackReferences and JetByteTools::Win32::CReferenceTracker to enable the tracking of calls to reference counting functions such as AddRef() or Release().

  • Added JetByteTools::Win32::StackWalker which is on a BSD license and is based on code from http://www.codeproject.com/threads/StackWalker.asp

  • Added JetByteTools::Win32::ISingleWriterMultipleReaderLock as we now have two implementations of a reader/writer lock.

  • Breaking Change JetByteTools::Win32::CSingleWriterMultipleReaderLock::Leave() now throws an exception if the lock is not locked.

  • Added JetByteTools::Win32::CSingleWriterMultipleReaderLockEx which is an implementation of JetByteTools::Win32::ISingleWriterMultipleReaderLock that allows recursive entry and also a writer to downgrade to a reader by simply calling JetByteTools::Win32::CSingleWriterMultipleReaderLockEx::EnterToRead() whilst holding a write lock.

  • Changed how catch(...) handlers are implemented within library code. See the release notes for Admin.h for more details.

  • Changes to JetByteTools::Win32::CException if JETBYTE_EXCEPTION_STACK_TRACES is defined to 1. When enabled exceptions derived from JetByteTools::Win32::CException will capture a call stack at the point where they are thrown. This can then be accessed via JetByteTools::Win32::CException::GetCallStack() and, optionally, displayed as part of the string that is returned from a call to JetByteTools::Win32::CException::GetWhere().

  • Changed how JetByteTools::Win32::CSEHException operates. Structured exception translation can be globally disabled by setting JETBYTE_TRANSLATE_SEH_EXCEPTIONS or JETBYTE_TRANSLATE_SEH_EXCEPTIONS_IN_DEBUGGER to 0 before building.

  • Added JetByteTools::Win32::CThreadedCallbackTimerQueue::OnThreadInitialised() and JetByteTools::Win32::CThreadedCallbackTimerQueue::OnThreadShutdown() which allow derived classes to call some code (such as to initialise COM) on the thread that is used to dispatch timers.

  • Changed how JetByteTools::Win32::CThreadPool works when maxThreads == minThreads. If we determine that the thread pool is a fixed size, i.e. maxThreads == minThreads then dispatch is done directly to the worker threads rather than via the dispatch port and the dispatcher thread. This is a slight performance optimisation and is useful in some situations.

  • Added JetByteTools::Win32::GUIDAsString() which converts a GUID to a string representation with or without leading and trailing braces.

  • Breaking Change Moved JetByteTools::CSmartBool to JetByteTools::Win32::CSmartBool.

  • Breaking Change Moved JetByteTools::TLinkedClass to JetByteTools::Win32::TLinkedClass.

  • Breaking Change Moved JetByteTools::TSingleton to JetByteTools::Win32::TSingleton.

  • Breaking Change Moved JetByteTools::TTypeSafeTypedef to JetByteTools::Win32::TTypeSafeTypedef.

I/O Tools Library - 6.1

  • Added the ability to restrict the number of pending writes for an instance of JetByteTools::IO::CAsyncFileWriter. You can now specify a maxPendingWrites in the constructor and if this is not 0 then a semaphore is created and used to control the number of writes that can be pending at any one time. When the maximum number of writes are pending the dispatch of new writes is delayed and writes effectively become synchronous. This can be used to prevent unconstrained resource usage.

  • Added JetByteTools::IO::CAsyncFileWriter::Callback::OnPendingWriteLimit() which is called each time the file writer reaches the limit of pending writes that it can have outstanding at any one time.

  • Added the ability to specify a pending write limit to the JetByteTools::IO::CAsyncFileWriter that is used by JetByteTools::IO::CRotatingAsyncFileLog.

  • Added the ability to specify a pending write limit to the JetByteTools::IO::CAsyncFileWriter that is used by JetByteTools::IO::CAsyncFileLog.

  • Fixed a race condition in how reads were issued by JetByteTools::IO::CAsyncFileReader.

  • Added a configuration option, JETBYTE_TRACK_IO_BUFFER_REFERENCES which when defined as 1 causes code to be inserted that tracks the reference counting that occurs on instances of JetByteTools::IO::CBuffer. If a buffer is over released (i.e. release is called on a buffer where the reference count is currently zero) then a trace of all calls to JetByteTools::IO::CBuffer::AddRef() and JetByteTools::IO::CBuffer::Release() will be printed to the debug trace output. If a buffer is destroyed and the reference count is not zero then a trace is also printed. Note that there is a considerable run-time cost for this functionality but it is non invasive and no external code changes are needed. See here http://www.lenholgate.com/archives/000867.html for more details.

  • Added JetByteTools::IO::CBufferReferenceTracker which is used to implement the reference tracking code that is detailed above.

  • Added the ability to specify that JetByteTools::IO::CBufferAllocator should allocate buffers using VirtualAlloc() with the additional option to allocate buffers on page boundaries. This can be useful if you want to control, exactly, the number of pages that your buffers use so that you can reduce the number of pages locked during I/O operations. Note that the allocator used is pretty simplistic and that it doesn’t return memory to the operating system until the allocator is destroyed. See here http://www.lenholgate.com/archives/000853.html for more details.

  • Added JetByteTools::IO::CBufferList which is a list which can contain instances of JetByteTools::IO::IBuffer and offsets and data lengths within them. A contiguous view onto these buffers can then be obtained. For example, if you add buffer 1 with an offset of 10 and a length of 10 and then buffer 2 with an offset of 12 and a length of 12 the value returned from JetByteTools::IO::CBufferList::GetTotalDataLength() will be 22 and the memory returned from JetByteTools::IO::CBufferList::GetContiguousMemory() will include 10 bytes of data from buffer 1 starting at offset 10 and 12 bytes from buffer 2 starting at offset 12. This can be useful for combining fragmented network messages where each message buffer also contains a header that needs to be skipped.

  • Added JetByteTools::IO::CSmartBufferList which is a ‘smart pointer’ for pointers to JetByteTools::IO::CBufferList.

  • Changed JetByteTools::IO::IAllocateBuffers::Flush() so that it returns a bool. The function now returns true if there were buffers present when the allocator was flushed.

  • Added the ability to specify to an instance of JetByteTools::IO::CBufferAllocator that you don’t want it to pool buffers at all.

Socket Tools Library - 6.1

  • Breaking Change we now allow exceptions to propagate out of JetByteTools::Socket::CConnectionMaintainingStreamSocketConnectionFilter::CancelConnectionRetries() rather than catching them in a catch(...) handler.

  • The constructors for JetByteTools::Socket::CDatagramSocketAllocator now default the spin count argument to 0 thus making it optional, previously it was required.

  • Changed JetByteTools::Socket::IAllocatePoolableSockets::ReleaseSockets() so that it returns a bool. The function now returns true if there were sockets present when the allocator was flushed.

  • Added JetByteTools::Socket::INamedServerShutdownCallback and JetByteTools::Socket::IServerShutdownCallback which can be passed to instances of JetByteTools::Socket::CNamedServerCollection or JetByteTools::Socket::CServerCollection respectively and which are used to call back to tell you as each server in the collection is shutdown. This is especially useful if you are shutting down a collection of servers from within a Windows service as you can notify the service control manager of your progress as each server is shutdown rather than having to guess and hope for the best that the timeout that you have specified is enough to shutdown an unknown number of servers in your collection. Note that null objects that implement each of these interfaces exist in the form of JetByteTools::Socket::CNullNamedServerShutdownCallback and JetByteTools::Socket::CNullServerShutdownCallback should you need them.

  • Added static versions of JetByteTools::Socket::CSocket::GetLocalAddress() and JetByteTools::Socket::CSocket::GetRemoteAddress() which return the addresses for the supplied socket.

  • Added the ability to specify to an instance of JetByteTools::Socket::CSocketAllocator that you don’t want it to pool sockets at all.

  • Added a configuration option, JETBYTE_TRACK_SOCKET_REFERENCES which when defined as 1 causes code to be inserted that tracks the reference counting that occurs on instances of all socket classes derived from JetByteTools::Socket::TAsyncSocket. If a socket is over released (i.e. release is called on a socket where the reference count is currently zero) then a trace of all calls to JetByteTools::Socket::TAsyncSocket<T>::AddRef() and JetByteTools::Socket::TAsyncSocket<T>::Release() will be printed to the debug trace output. If a socket is destroyed and the reference count is not zero then a trace is also printed. Note that there is a considerable run-time cost for this functionality but it is non invasive and no external code changes are needed. See here http://www.lenholgate.com/archives/000867.html for more details.

  • Added JetByteTools::Socket::CSocketReferenceTracker which is used to implement the reference tracking code that is detailed above.

  • Added an exception handler to JetByteTools::Socket::CStreamSocketConnectionManager::FilterConnectionEstablished() which will report the error and abort the connection on the socket in question should an exception escape from either JetByteTools::Socket::IFilterStreamSocketConnections::FilterConnectionEstablished() or JetByteTools::Socket::IStreamSocketConnectionManagerCallback::OnConnectionEstablished().

  • Fixed a race condition bug in JetByteTools::Socket::CStreamSocketServerEx whereby code waiting for the server to shutdown would complete its wait before the server had completely finished with the last buffer that was in use when the final socket was closed. This could, potentially, have resulted in a race condition between the cleanup and destruction of the buffer allocator that was being used and the final release of the buffer that was used in the final socket’s final operation. It’s very unlikely that you’d see this in production code, but it was causing a test to fail.

OpenSSL Tools Library - 6.1

  • No changes.

SChannel Tools Library - 6.1

  • Breaking Change all code has been moved from the JetByteTools::SChannel namespace to the JetByteTools::SSPI::SChannel namespace.

  • Breaking Change the following classes have been moved from the JetByteTools::SChannel namespace to the JetByteTools::SSPI namespace.

  • JetByteTools::SSPI::CCountedCredentialsHandle

  • JetByteTools::SSPI::CCountedSecurityContext

  • JetByteTools::SSPI::CException

  • JetByteTools::SSPI::CSecurityBuffer

  • JetByteTools::SSPI::TSecurityBuffers

  • JetByteTools::SSPI::CSmartCredentialsHandle

  • JetByteTools::SSPI::CSmartSecurityContext

  • JetByteTools::SSPI::CToken

This was done to facility reuse by the code in the new SSPINegotiate Tools library which lives in the JetByteTools::SSPI::Negotiate namespace.

  • Improved support for renegotiating connections.

  • Breaking Change renamed JetByteTools::SSPI::SChannel::ClientAuthenicationRequirements::RequireClientCertificate to JetByteTools::SSPI::SChannel::ClientAuthenicationRequirements::RequireClientAuthentication.

SSPINegotiate Tools Library - 6.1

SSPI Tools Library - 6.1

  • A new library that contains the code that is shared between SSPI Negotiate and SChannel.

PerfMon Tools Library - 6.1

  • Bug fix to JetByteTools::PerfMon::CPerformanceDataBlock::AllocateObjectInstance() for a bug which would cause object instances to be allocated incorrectly under certain circumstances. See here http://www.lenholgate.com/archives/000847.html for more details.

Service Tools Library - 6.1

  • Complete redesign of the whole library… See here http://www.lenholgate.com/archives/000850.html for details. Here are some of the changes:

  • Callbacks into user code now rely on a callback interface rather than subclassing of the service base class.

  • Separated the single instance and the multi instance service code into two separate base classes; JetByteTools::Service::CServiceManager and JetByteTools::Service::CServiceInstanceManager, both of which inherit from JetByteTools::Service::CServiceManagerBase.

  • We now support all of the ’new’ service control functionality:

  • SERVICE_CONTROL_PRESHUTDOWN

  • SERVICE_CONTROL_PARAMCHANGE

  • SERVICE_CONTROL_NETBINDADD

  • SERVICE_CONTROL_NETBINDREMOVE

  • SERVICE_CONTROL_NETBINDENABLE

  • SERVICE_CONTROL_NETBINDDISABLE

  • SERVICE_CONTROL_HARDWAREPROFILECHANGE

  • SERVICE_CONTROL_SESSIONCHANGE

  • SERVICE_CONTROL_DEVICEEVENT

  • SERVICE_CONTROL_POWEREVENT

  • and custom control values between 128 and 255…

  • All OnException() callbacks into user code are now wrapped in exception handlers which trap and swallow all exceptions. You’re not allowed to throw out of these callback handlers!

  • Redesign to remove all race conditions relating to service shutdown. See here http://www.lenholgate.com/archives/000848.html for details.

  • Service installation and configuration now supports all of the ’new’ service configuration options:

  • SERVICE_FAILURE_ACTIONS

  • SERVICE_REQUIRED_PRIVILEGES_INFO

  • SERVICE_SID_INFO

  • SERVICE_DELAYED_AUTO_START_INFO

  • SERVICE_FAILURE_ACTIONS_FLAG

  • SERVICE_PRESHUTDOWN_INFO

  • All interaction with the system’s Service Control Manager is via interfaces which allow for much more thorough testing.

CLR Hosting Tools Library - 6.1

  • No changes.

Full details of the licensed version of the code are available at http://wwww.serverframework.com.

Full details of the free version of the code are available here.

Doxygen documentation for the latest relase is available here.

If you’re an existing client and you’d like these changes let me know.