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.2
- We now support Visual Studio 2010. At present the code has only been tested with the beta and release candidate versions.
- 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 inConfig.h
is shown for each option:JETBYTE_TINY_XML_2_5_3
- enabled by default. From this release TinyXML version 2.5.3 is available and is used by default in XMLTools. If you would prefer to continue to use TinyXML 2.5.2 then defineJETBYTE_TINY_XML_2_5_3
to 0 in your Config.h- You can enable the
FILE_SKIP_SET_EVENT_ON_HANDLE
flag of SetFileCompletionNotificationModes() for stream sockets, datagram sockets,JetByteTools::IO::CAsyncFileWriter
orJetByteTools::IO::CAsyncFileReader
using the following configuration options:JETBYTE_PERF_STREAM_SOCKETS_SKIP_EVENT_ON_HANDLE
- enabled by default.JETBYTE_PERF_DATAGRAM_SOCKETS_SKIP_EVENT_ON_HANDLE
- enabled by default.JETBYTE_PERF_FILE_WRITER_SKIP_EVENT_ON_HANDLE
- enabled by default.JETBYTE_PERF_FILE_READER_SKIP_EVENT_ON_HANDLE
- enabled by default.
Config.h
. See here for more details. - You can enable the
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
flag of SetFileCompletionNotificationModes() for stream sockets, datagram sockets,JetByteTools::IO::CAsyncFileWriter
orJetByteTools::IO::CAsyncFileReader
. using the following configuration options:JETBYTE_PERF_STREAM_SOCKETS_SKIP_COMPLETION_PORT_ON_SUCCESS
- enabled by default.JETBYTE_PERF_DATAGRAM_SOCKETS_SKIP_COMPLETION_PORT_ON_SUCCESS
- DISABLED by default.JETBYTE_PERF_FILE_WRITER_SKIP_COMPLETION_PORT_ON_SUCCESS
- DISABLED by default.JETBYTE_PERF_FILE_READER_SKIP_COMPLETION_PORT_ON_SUCCESS
- enabled by default.
Config.h
. Note that this option is only enabled by default for stream sockets. You can, of course, enable the option by defining the appropriate configuration option to 1 in yourConfig.h
BUT there is a known bug with enabling this option for UDP sockets on Windows Vista and Windows 7 which may cause resource leaks and we have been unable to exercise the new code for theJetByteTools::IO::CAsyncFileWriter
during testing and so have not enabled the code at this time. See here for more details. JETBYTE_DEBUG_BREAK_ON_CONNECTIONS_ACTIVE_DURING_DESTRUCTION
- enabled by default. If enabled a breakpoint is triggered if you are in the debugger and there are connections active when a connection manager is destroyed. The connection manager base class cannot wait for these connections to complete as the callback that it uses to notify your code that connections have completed will likely have been destroyed by the time this code is executed. You should always have waited for a shutdown to complete and not created any connections again after that point before destroying your connection manager. You CAN and SHOULD wait for shutdown in your own derived class's destructor! Enabling this option helps you spot situations where you are NOT waiting correctly in your own code.JETBYTE_DUMP_SOCKET_READ_AND_WRITE_DATA_TO_DEBUG_LOG
- disabled by default. When enabled the low level socket I/O code dumps complete details of all data sent and received to the default debug trace log. This can be useful when developing connection filters. Note that this should not be left enabled as the debug generation is time consuming.JETBYTE_DISABLE_VS2005_DEBUG_UUIDLIB_CHECK
- has been removed. It was too difficult to detect installations that needed it and you can fix the problem that it tried to work around with the hotfix that we link to from here.- We now create typedefs for
DWORD
andBYTE
in Types.h. This means that we don't need to include <wtypes.h> quite so often.
- Added
JetByteTools::Win32::CAtomicBool
- a simple boolean class which provides an atomic way to query and toggle the value usingInterlockedCompareExchange()
- Fixed a memory leak bug in
JetByteTools::Win32::CCallStack
where we were deleting an array withdelete
rather thandelete []
. - Added
JetByteTools::Win32::CConditionalSmartPointer
- a smart pointer which can be told, during construction or assignment, not to act as a smart pointer. This can be useful if sometimes you own some memory and sometimes you don't and you want to hold the memory in a smart pointer when you DO own it... - Breaking Change All instances of
InitiateShutdown()
have been changed toBeginShutdown()
this is to remove the issue with the Win32InitiateShutdown()
function which is conditionally defined as eitherInitiateShutdownA()
orInitiateShutdownW()
and which could then cause issues. The following classes are affected:JetByteTools::Win32::CDirectoryChangeMonitor
JetByteTools::Win32::ICollectableThreadPool
JetByteTools::Win32::CIOCPWorkerThread
JetByteTools::Win32::CThreadedCallbackTimerQueue
JetByteTools::Win32::CThreadPool
JetByteTools::Win32::CThreadPoolCollection
- Added
JetByteTools::Win32::ICompressData
an interface that represents a stateless data compressor/decompressor. At present the only implementation of this isJetByteTools::ZLib::CDataCompressor
. JetByteTools::Win32::ISingleWriterMultipleReaderLock::Reader
now takes aconst ISingleWriterMultipleReaderLock
reference in its constructor as entering to read is a logicallyconst
operation for most classes that would be using theISingleWriterMultipleReaderLock
lock.- Added
JetByteTools::Win32::IWaitable::IsSignalled()
which callsWait()
with a timeout of zero to determine if the object is currently signalled. This gets around the need to cast the zero toJetByteTools::Milliseconds
to avoid ambiguity. - Fixed
JetByteTools::Win32::CNamedIndex::FindOrAdd()
so that it only checks to see if the index collection is locked if it needs to add a new index. - Added an optional null pointer dereference check to
JetByteTools::Win32::TReferenceCountedSmartPointer::operator->()
. IfJETBYTE_REFERENCE_COUNTED_SMART_POINTER_THROW_ON_NULL_REFERENCE
is enabled then we throw an exception if the reference is null at point of use. - Added
JetByteTools::Win32::CRegistryConfiguration
an implementation ofJetByteTools::Win32::IConfiguration
which reads data from a specify set of registry keys. - Added
JetByteTools::Win32::CSmartBool::operator bool()
. - Added a new overload to
JetByteTools::Win32::CStringConverter::AtoBSTR()
. - Added some new conversion formats to
JetByteTools::Win32::CSystemTime
. You can now pass date/times in any of the following string formats to theJetByteTools::Win32::CSystemTime
constructor.YYYYMMDD HHMMSS
YYYYMMDD HHMMSSMMM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.MMM
- Added
JetByteTools::Win32::CSystemTime::GetAsHHMMSSMMM()
. - Added
JetByteTools::Win32::CSystemTime::GetAsDatabaseDateTimeStamp()
which returns the date/time asYYYY-MM-DD HH:MM:SS.MMM
- Added
JetByteTools::Win32::CSystemTime::ContainsDate()
which returnstrue
if the date portion of date/time is valid. - Breaking Change
JetByteTools::Win32::CTempDirectory::RemoveContents()
now removes the contents of sub-directories as well as files within the temporary directory. - Breaking Change
JetByteTools::Win32::CThread::WasStarted()
has been removed and replaced byJetByteTools::Win32::CThread::IsRunning()
. This is because instances ofJetByteTools::Win32::CThread
can now be restarted after they have been shutdown. - Fixed a rare memory leak with
JetByteTools::Win32::CThreadedCallbackTimerQueue
. We now useJetByteTools::Win32::CConditionalSmartPointer
to hold the timer queue so that failed construction of theJetByteTools::Win32::CThreadedCallbackTimerQueue
after the timer queue has been created causes the timer queue to be destroyed correctly. - Added conditional code for VS2002 and VS2003 for
JetByteTools::Win32::GetStringLengthAsDWORD()
and all other versions so that we are using the templated version for VS2005 and later and only using custom code for those compilers that don't support the template code. This is to make it easier to move away from the custom code when we drop support for the older compilers. JetByteTools::Win32::CWaitableCounter::Increment()
now returnstrue
if the value was incremented from zero.JetByteTools::Win32::CWaitableCounter::Decrement()
now returnstrue
if the value was decremented to zero.- Added
JetByteTools::Win32::CWaitableCounter::Add()
which allows you to add an arbitrary amount to a waitable counter and correctly toggles the various events if the counter passes through zero. - Added
JetByteTools::Win32::CWaitableCounter::Subtract()
which allows you to subtract an arbitrary amount from a waitable counter and correctly toggles the various events if the counter passes through zero. - Added
JetByteTools::Win32::CWaitableCounter::Incrementer::LeaveIncremented()
. - Added
JetByteTools::Win32::CWaitableCounter::Decrementer::LeaveDecremented()
. JetByteTools::Win32::CException
now strips trailing new lines from error messages obtained byJetByteTools::Win32::GetLastErrorMessage()
.- Added
JetByteTools::Win32::CSEHException::GetCallStack()
which returns the callstack that was active when theJetByteTools::Win32::CSEHException
was generated.
- We now check for numeric overflow when we're calculating the total size of the buffers in
JetByteTools::IO::CMultiBufferHandle::GetUsed()
. - Fixed a bug in
JetByteTools::IO::CAsyncFileWriter::HandleWriteRequest()
which could cause a race condition between the buffer allocator's destruction and the last operation that we perform on a buffer that has been allocated from it. Basically we signal that the last write is complete after we've finished fiddling with the buffers that we've been using. - Added conditional code to allow
FILE_SKIP_SET_EVENT_ON_HANDLE
andFILE_SKIP_COMPLETION_PORT_ON_SUCCESS
to be enabled on the file handle used byJetByteTools::IO::CAsyncFileWriter
. See theJETBYTE_PERF_FILE_WRITER_SKIP_EVENT_ON_HANDLE
andJETBYTE_PERF_FILE_WRITER_SKIP_COMPLETION_PORT_ON_SUCCESS
configuration options inConfig.h
- Added conditional code to allow
FILE_SKIP_SET_EVENT_ON_HANDLE
andFILE_SKIP_COMPLETION_PORT_ON_SUCCESS
to be enabled on the file handle used byJetByteTools::IO::CAsyncFileReader
. See theJETBYTE_PERF_FILE_READER_SKIP_EVENT_ON_HANDLE
andJETBYTE_PERF_FILE_READER_SKIP_COMPLETION_PORT_ON_SUCCESS
configuration options inConfig.h
- Fixed
JetByteTools::IO::CBufferAllocator::RequestUserDataSlot()
so that it only checks to see if the index collection is locked if an exception is thrown whilst manipulating it. - Removed <wtypes.h> from
IAsyncIOStream.h
- Added
JetByteTools::IO::CInOrderBufferList::SetInitialSequenceNumber()
and allow the initial sequence number to be passed into the constructor. - Fixed
JetByteTools::IO::CInOrderBufferList
sequence number wrap issues. - Breaking Change All instances of
InitiateShutdown()
have been changed toBeginShutdown()
this is to remove the issue with the Win32InitiateShutdown()
function which is conditionally defined as eitherInitiateShutdownA()
orInitiateShutdownW()
and which could then cause issues. The following classes are affected:JetByteTools::IO::IOPool
JetByteTools::Socket::CCompressingDatagramSocketConnectionFilter
- a filter which uses an instance of JetByteTools::Win32::ICompressData
to compress the data stream.JetByteTools::Socket::CFilteringStreamSocketConnectionManager
JetByteTools::Socket::CFilteringStreamSocketServer
JetByteTools::Socket::CFilteringStreamSocketServerEx
JetByteTools::Socket::ICreateFilteredStreamSocketConnections
JetByteTools::Socket::IFilterStreamSocketConnections
. Most of the function signatures have changed because we've done away with the FilterProcessing
enum
and now indicate that a filter has 'swallowed' a call by simply not returning the buffer that it was passed in. Filter methods now generally return a buffer which is passed on to the next filter in the chain and eventually on to the client code callback. A filter can return any buffer, not just the buffer that it was passed, but it should be sure to copy the sequence number if it replaces the input buffer with one of its own. By returning null
the filter can signal that the call stops there, it may pass buffers on to later filters directly using JetByteTools::Socket::IManageStreamSocketConnectionFilters
or simply swallow the request. Note that only JetByteTools::Socket::IFilterStreamSocketConnections::RequestRead()
differs in that it returns a bool
to indicate if processing should continue; this is due to the fact that the input buffer is optional anyway and a null
buffer is no indication of anything special. This change has knock on changes to the following classes as they implement or deal with JetByteTools::Socket::IFilterStreamSocketConnections
.
JetByteTools::Socket::CCompressingStreamSocketConnectionFilter
JetByteTools::Socket::CConnectionMaintainingStreamSocketConnectionFilter
JetByteTools::Socket::CFlowControlStreamSocketConnectionFilter
JetByteTools::Socket::CNullStreamSocketConnectionFilter
JetByteTools::Socket::CReadSequencingStreamSocketConnectionFilter
JetByteTools::Socket::CReadTimeoutStreamSocketConnectionFilter
JetByteTools::Socket::CFilteringStreamSocketConnectionManager
JetByteTools::Socket::CFilteringStreamSocketServer
JetByteTools::Socket::CFilteringStreamSocketServerEx
JetByteTools::Socket::CFilteringDatagramSocketServer
and JetByteTools::Socket::CFilteringDatagramConnectionManager
if you wish to use filters with datagram sockets. The following filters are currently available:
JetByteTools::Socket::CCompressingDatagramSocketConnectionFilter
- a filter which uses an instance ofJetByteTools::Win32::ICompressData
to compress the contents of each datagram.JetByteTools::Socket::CReadTimeoutDatagramSocketConnectionFilter
- a filter which provides a read timeout for datagram sockets.
JetByteTools::Socket::TCPBufferSize
to JetByteTools::Socket::SocketBufferSize
as it is now used to set send/recv buffer sizes for datagram sockets as well as TCP (stream) sockets.JetByteTools::Socket::IRenderAddresses::GetPort()
which returns the port of a given address.JetByteTools::Socket::IStreamSocketCallback::OnConnectionClosure()
,
JetByteTools::Socket::IDatagramSocketCallback::OnConnectionClosure()
and JetByteTools::Socket::IDatagramServerSocketCallback::OnConnectionClosure()
which provide a reason for the connection closure in the form of a value from the JetByteTools::Socket::ConnectionClosureReason
enum. Note that JetByteTools::Socket::IStreamSocketCallback::OnConnectionClosed()
, etc, MAY be removed in a future release of the framework.JetByteTools::Socket::ILimitConnections::GetOverallLimit()
which returns the total number of connections that a connection limiter allows.JetByteTools::Socket::CConnectionLimiter::NoLimit
to JetByteTools::Socket::ILimitConnections::NoLimit
so that it can be returned by JetByteTools::Socket::ILimitConnections::GetOverallLimit()
for a connection limiter which does not have a limit.JetByteTools::Socket::IDatagramSocketConnectionManagerCallback::OnBindCompleted()
which is called when a datagram socket has successfully been bound to a local address.JetByteTools::Socket::IDatagramSocketConnectionManagerCallback::OnSocketCreated()
is no longer marked as 'no throw'.JetByteTools::Socket::IDatagramSocketConnectionManagerCallback::OnConnectionEstablished()
is no longer passed a pointer to user data.JetByteTools::Socket::IDatagramSocketConnectionManagerCallback::OnAllConnectionsAborted()
, JetByteTools::Socket::IDatagramSocketConnectionManagerCallback::OnShutdownInitiated()
and JetByteTools::Socket::IDatagramSocketConnectionManagerCallback::OnShutdownComplete()
.OnServerShutdownComplete()
is only ever called once.InitiateShutdown()
have been changed to BeginShutdown()
this is to remove the issue with the Win32 InitiateShutdown()
function which is conditionally defined as either InitiateShutdownA()
or InitiateShutdownW()
and which could then cause issues. The following classes are affected:
JetByteTools::Socket::IServerControl
JetByteTools::Socket::CServerCollection
JetByteTools::Socket::CNamedServerCollection
JetByteTools::Socket::CDatagramSocketConnectionManager
JetByteTools::Socket::CDatagramSocketServer
JetByteTools::Socket::CStreamSocketConnectionManager
JetByteTools::Socket::CStreamSocketServer
JetByteTools::Socket::CStreamSocketServerEx
FILE_SKIP_SET_EVENT_ON_HANDLE
and FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
to be enabled on sockets. See the JETBYTE_PERF_STREAM_SOCKETS_SKIP_EVENT_ON_HANDLE
, JETBYTE_PERF_DATAGRAM_SOCKETS_SKIP_EVENT_ON_HANDLE
, JETBYTE_PERF_STREAM_SOCKETS_SKIP_COMPLETION_PORT_ON_SUCCESS
and JETBYTE_PERF_DATAGRAM_SOCKETS_SKIP_COMPLETION_PORT_ON_SUCCESS
configuration options in Config.h
JetByteTools::Socket::IAcceptDatagramSocketConnectionFilters
, JetByteTools::Socket::IFilterableDatagramSocket
, JetByteTools::Socket::IFilterDatagramSocketConnections
and JetByteTools::Socket::IManageDatagramSocketConnectionFilters
to support datagram socket filtering.JetByteTools::Socket::CReadSequencingStreamSocketConnectionFilter::FilterSocketReleased()
where we were deleting a void
pointer rather than casting it to its correct class before deletion.JetByteTools::Socket::CReadTimeoutStreamSocketConnectionFilter::SetupReadTimeout()
which can be used to set the details of a read timeout without actually setting the timer.JetByteTools::Socket::CSocketReferenceTracker::DumpReferences()
to make it easy to dump a socket's references.- Refactored the code to remove duplication. This resulted in the creation of
JetByteTools::OpenSSL::CSecureConnectShim
andJetByteTools::OpenSSL::CStreamSocketConnectionFilter
. - Templatised the code in
JetByteTools::OpenSSL::CStreamSocketServer
intoJetByteTools::OpenSSL::TStreamSocketServer
to allow the creation ofJetByteTools::OpenSSL::CStreamSocketServerEx
and the newJetByteTools::OpenSSL::CStreamSocketServer
. - Added
JetByteTools::OpenSSL::CStreamSocketServerExCallback
. - Breaking Change to
JetByteTools::OpenSSL::CStreamSocketConnectionFilter
due to function signature changes inJetByteTools::Socket::IFilterStreamSocketConnections
.
- Refactored the code to remove duplication. This resulted in the creation of
JetByteTools::SSPI::SChannel::CSecureConnectShim
,JetByteTools::SSPI::SChannel::CSecureConnectData
,JetByteTools::SSPI::SChannel::CFilterHolder
andJetByteTools::SSPI::SChannel::CStreamSocketConnectionFilter
. - Templatised the code in
JetByteTools::SSPI::SChannel::CStreamSocketServer
intoJetByteTools::SSPI::SChannel::TStreamSocketServer
to allow the creation ofJetByteTools::SSPI::SChannel::CStreamSocketServerEx
and the newJetByteTools::SSPI::SChannel::CStreamSocketServer
. - Added
JetByteTools::SSPI::SChannel::CStreamSocketServerExCallback
. - Breaking Change to
JetByteTools::SSPI::SChannle::CStreamSocketConnectionFilter
due to function signature changes inJetByteTools::Socket::IFilterStreamSocketConnections
.
- Refactored the code to remove duplication. This resulted in the creation of
JetByteTools::SSPI::Negotiate::CSecureConnectShim
,JetByteTools::SSPI::Negotiate::CClientImpersonator
,JetByteTools::SSPI::Negotiate::CFilterHolder
andJetByteTools::SSPI::Negotiate::CStreamSocketConnectionFilter
. - Templatised the code in
JetByteTools::SSPI::Negotiate::CStreamSocketServer
intoJetByteTools::SSPI::Negotiate::TStreamSocketServer
to allow the creation ofJetByteTools::SSPI::Negotiate::CStreamSocketServerEx
and the newJetByteTools::SSPI::Negotiate::CStreamSocketServer
. - Added
JetByteTools::SSPI::Negotiate::CStreamSocketServerExCallback
. - Breaking Change to
JetByteTools::SSPI::Negotiate::CStreamSocketConnectionFilter
due to function signature changes inJetByteTools::Socket::IFilterStreamSocketConnections
.
- No changes.
- Removed the whole broken concept of
JETBYTE_PERFMON_SAFE_BUT_SLOW_64BIT_OPERATIONS
which allowed 64 bit wide counters to be accessed in a non atomic manner if the variousInterlockedXXX64()
intrinsics weren't available if it was set to zero. Now there's no way of turning off the lock used to ensure atomic increments of 64 bit values if required. This will prevent 64 bit counter values from being completely broken if compiled withJETBYTE_PERFMON_SAFE_BUT_SLOW_64BIT_OPERATIONS
set to zero on a platform that doesn't supportInterlockedXXX64()
.
- Breaking Change to
JetByteTools::Service::IServiceCallbacks::InitialiseService()
which now returns abool
(rather thanvoid
) wherefalse
indicates that the initialisation failed and that the service should shutdown.
- Added some initial support for the new hosting API with
JetByteTools::CLRHosting::CCLRMetaHost
andJetByteTools::CLRHosting::CCLRRuntimeInfo
.
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. I'm currently in the final phases of testing the release. I expect it will be ready to ship by the end of next week at the latest.
great work!!
finally it comes!
is there any chance that you release another version of the free code?? i am really expecting that .
I think it's unlikely that I'll ever release anything but a bug fix release for the free code and right now there are no outstanding bugs.
The licensed code is considerably different to the free code now and it's only the license fees and the consulting that often comes from people wanting to extend the licensed code in various new directions that causes the licensed code to keep moving forwards. If I gave it all away for free there'd be less incentive for me to improve it...
The free code works fine for many people and, if you have the time and inclination, you can build complex systems from it and extend it in the same direction that the licensed code has been taken. The licensed code is there for people who prefer to have support, consulting and the more advanced features, and, once you're building production server systems, the time saved by using the licensed code and having me on hand to support the code and your designs is easily worth the cost of the license fee.
Why don't you have public price information?
It's mainly historical; I never have and it hasn't seemed to do me any harm so there hasn't seemed to be a need to do so. Initially (back in 2003) the pricing was more fluid than it is now as I was trying to work out what the code was worth and that was the reason that the prices weren't published. These days the pricing hasn't changed for over 3 years and so there's less reason not to have a price list somewhere. In fact, my list of things to do includes a more formal website with pricing etc. I expect that there's actually no real reason not to have prices on the licensing information page...
However, I like to be able to track who's interested in the licensed code as it means that I get more information about the kinds of companies that are interested and the kinds that actually buy. It also means that I can track the conversion rate between enquiries and sales which I couldn't do with a public price list as I wouldn't be able to know who was interested except for the price.
A steady stream of enquiries with a healthy conversion rate means has tended to convince me that the current methods works OK.
Does lack of public price information deter you from sending an email asking about licensing terms and prices?
I now have full pricing information available here: http://www.serverframework.com/prices.html