Written by Jeremy Friesner, Last Updated 7/7/2015
Subscribe to the MUSCLE developer's mailing list
Watch a short video of a MUSCLE server synchronizing multiple clients in real time
Read the Beginner's Guide to MUSCLE
Read the Guide to making a custom MUSCLE server
Demonstration of how to add multithreading to a custom MUSCLE server (v1.04)
Read the BeShare and MUSCLE BeNews article
MUSCLE is licensed under the BSD Open Source License
Study the Java Client API Javadocs
key: - new feature
* bug fixed
o other
6.23 Release 7/7/2015
- The StringMatcher class now has a IsPatternListOfUniqueValues()
method that returns true iff the that pattern is a comma-separated
list of non-wildcarded values.
o NodePathMatcher::DoTraversalAux() was using a Queue as a cache,
which could be inefficient due to O(N^2) lookups in certain cases.
Replaced it with a Hashtable for better performance.
o Optimized the NodePathMatcher algorithm to be more efficient
when node-paths that include clauses that are long lists of
comma-separated node names.
* SharedFilterSessionFactory.cpp wouldn't compile if -DMUSCLE_AVOID_IPV6
was specified on the compile line. Fixed.
6.22 Released 6/11/2015
- Added an IsWaitingForEvents() method to ReflectServer class,
so that a (user-supplied) watchdog thread can observe when the
ReflectServer is blocked waiting for I/O vs when it is doing
something.
- Added Mika's vc++14 subdirectory, which contains Visual C++
project files for Visual Studio 2015.
- DataNode::GetAncestorNode() now takes an optional second argument
that tells it what to return if the ancestor node isn't found.
o Added some more Cygwin/MinGW compatibility changes contributed
by Mika Lindqvist.
o Rewrote some of the node-traversal callback methods so that they
no longer pass an integer argument by casting it to (void *).
* Tweaked various files to fix warnings reported by cppcheck 1.69.
* The stdout-display in qt_muscled wasn't read-only. Fixed.
6.21 Released 5/14/2015
o Merged in Mika Lindqvist's patch to make the StackWalker code
use less stack space.
o Merged in Mika Linkdqvist's patches for better Cygwin compatibility.
* Made the StackWalker code a bit more robust.
* Merged in Mika Lindqvist's patch to the VC++12 projects
to link debug builds against the MultiThreadedDebug
run time library rather than the MultiThreaded library.
* Fixed a couple of const-correctness issues in the StackWalker code.
o Modified the Windows implementation of GetNetworkInterfaceInfos()
to not specify an interface index for IPv6 network device address
::1, as doing so causes UDP-packet-routing problems under Windows 7.
6.20 Released 4/20/2015
- Added a new sub-folder besupport/admin_gui. It contains
Fredrik Modeen's GUI shell for more easily running muscled
under BeOS or Haiku.
- Added new MUSCLE-specific versions of some potentially-insecure
(per Microsoft) C functions to MuscleSupport.h: muscleFopen(),
muscleStrcpy(), muscleStrncpy(), muscleSprintf(), and
muscleSnprintf(). These get expanded out to the appropriate
system-specific equivalent, so that e.g. under Windows we can
use the CRT-secure Windows-only equivalents, while not having
to put #ifdefs all over the code to keep it compiling elsewhere.
- Added Visual C++ 2013 project files, courtesy of Mika Lindqvist
(in the new "vc++12" subfolder)
o Renamed the vc++ subfolder to vc++8 to make it more obvious
that the project files it contains are for Visual Studio 2008.
o MUSCLE classes that should not be subclasses are now tagged
with the MUSCLE_FINAL_CLASS keyword so that when compiled
with -DMUSCLE_USE_CPLUSPLUS11 the compiler will produce a
compile-time error if they are subclassed.
o Modified the QueueGatewayMessageReceiver and StringMatcherQueue
classes to no longer subclass from the Queue class, since
subclassing from Queue is no longer allowed. Instead, they
now include a Queue object as a member variable and provide
accessors to that object.
o Modified the ObjectPool class to no longer subclass the
ObjectNode internal class from the templated-type, since
the templated-type might now be marked as "final".
o Replaced various of the aforementioned calls with their
muscle*() equivalents in the codebase.
o Merged in some patches contributed by Mika Linqvist to avoid
CRT security warnings when compiling under MSVC 2013.
o Removed all calls to strcat() and strncat(), as their string
truncation semantics are too difficult for me to reason about
reliably. The rewritten code is also generally more efficient.
o Modified DefaultFileLogger::CloseLogFile() to reduce its
stack usage.
o Modified GetNetworkInterfaceInfos() to not specify an interface
index for IPv6 network device address ::1, as doing so causes
UDP-packet-routing problems under MacOS/X.
* Fixed a const-correctness problem in ConvertMessages.cpp.
* Removed a compiler warning (from SysLog.cpp) about
GetVersionA() not working usefully under Windows 8 and higher.
* Applied Mika Lindqvist's patch to fix some potential
memory leaks in regcomp.c
* Applied Mika Lindqvist's patch to make the Windows
"StackWalker" stack-trace-generation routine Unicode-compliant.
6.12 Released 4/6/2015
- The Python message_transceiver_thread class will now
fall back to connecting via IPv4 if the supplied hostname
cannot be expanded to an IPv6 address (and vice versa).
o Added a NotCopyable base class to various classes
(Socket, DataNode, AbstractReflectSession, etc) so that
the compiler will verify that they are not being copied.
o The StringMatcher class now interprets any simple wildcard
string starting with a backtick character (`) as indicating
a non-simple regex string. That way it is possible to use
the standard regex functionality, if desired, in contexts
that otherwise provide no way to indicate that a string
is meant to be a full regex string and not a simple wildcard
string (e.g. in MUSCLE subscription strings)
o Tweaked the codebase to get rid of a number of style
problems and minor errors that were reported by cppcheck.
* Added a patch to the captive regex library to fix a
potential int32-overrun in regcomp(). Thanks to Mika
Lindqvist for supplying me with the patch.
* Merged in some patches from Mika Lindqvist to avoid
some warnings when compiling in a 64-bit environment.
6.11 Released 2/2/2015
- When compiled under Windows, SetupSystem.cpp now contains
#pragma commands so that necessary Windows-libraries will
be automatically linked in. This means the user no longer
has to spend time chasing down so many linker errors when
setting up a new project file.
o MutexGuard's argument is now a const reference, since
Mutex::Lock() and Mutex::Unlock() are const methods.
o Removed AbstractReflectSession::GetDefaultHostName()
and replaced it with a new method named
AbstractReflectSession::GenerateHostName(). The new
method lets the session subclass choose a custom
hostname for the session even if the IP address
determination didn't fail.
o Added some private/unimplemented method overloads for
MessageTransceiverThread::AddNewConnectSession() and
QMessageTransceiverHandler::SetupAsNewConnectSession()
so that if the caller tries to call these methods
with timeout-values but forgets to include the
(expandLocalhost) argument, the error will be caught
at compile-time rather than causing unexpected run-time
behavior.
6.10 Released 12/12/2014
- The DetectNetworkConfigChangesSession class now has
ComputerIsAboutToSleep() and ComputerJustWokeUp()
callback methods that are called at the times indicated
by their names. Currently this functionality is
implemented only under MacOS/X and Windows.
o Added work-arounds for gcc-3.x SFINAE incompatibilities
to MuscleSupport.h
o Updated the muscle.dox file using doxygen -u so that
it is now up-to-date (as of DOxygen 1.8.8)
* If a string like "for 10 seconds" was passed to
ParseHumanReadableTimeIntervalString(), the "for"
prefix would cause the returned value to be twice
what it was expected to be. Fixed.
6.09 Released 11/3/2014
- Added a (preferIPv6) argument to GetHostByName(). If
left as true (the default value), GetHostByName() will
prefer to return an IPv6 address over an IPv4 address.
- Added support for a DEBUG_LARGE_MEMORY_ALLOCATIONS_THRESHOLD
compiler-flag into GlobalMemoryAllocator.cpp. When this
flag is set to a value (in bytes), any memory allocations
greater than the value will result in a message and a stack
trace being printed to stdout.
- When MUSCLE_USE_CPLUSPLUS11 is defined, the PODHashFunctor
class will provoke a compile-time error if the program tries to
use a struct or class as a KeyType in a Hashtable and the
struct/class does not have a "uint32 HashCode const" method
defined. (Previously the code would compile without error, and
then hashing errors would occur at runtime due to the object's
padding bytes being uninitialized)
* The MCRASH() macro now calls abort() rather than assert(false),
so that a crash will actually occur, even if the code was
compiled with -DNDEBUG.
o The Windows implementation of MCRASH() now calls RaiseException(),
so that the crash will behave more like an actual caused-by-a-bug
crash (in particular, a Windows Structured Exception will be raised)
o Updated SendDataUDP() to work around a "feature" in OS/X 10.10 (aka
Yosemite) that causes setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF)
to fail when setting the socket's interface-index value back to 0.
6.08 Released 10/10/2014
- Added a ShrinkToFit() convenience method to the Queue,
Hashtable, and String classes. This method shrinks the
object so that the amount of memory it has allocated internally
matches the size of the data it is actually holding.
- Hashtable::EnsureSize() and Queue::EnsureSize() now take an optional
(allowShrink) argument, that (if set to true) allows the object's
internally-allocated array to be reallocated smaller if it is larger
than necessary.
o Tweaked the buffer-expansion behavior of the String class to
be a bit more efficient.
* Added a guard against a potential infinite recursion that
could occur while logging an "OUT OF MEMORY" error after
a memory allocation failure, if a LogCallback tried to
allocate memory.
6.07 Released 9/18/2014
- Added a GlobalPrintRecyclersToStream() method to the
AbstractObjectRecycler class, for better debugging and
analysis of the ObjectPool's memory usage.
- Added an abstract PrintToStream() method to the
AbstactObjectRecycler class, and a concrete implementation
of that method to the ObjectPool and ThreadPool classes.
- Added a testobjectpool.cpp test program to the tests
folder, as a quick sanity check for the ObjectPool class.
- Java performance improvement from Bryan Varner: Switched to a
direct byte buffer, which is allocated by the OS outside of
the GC's managed space.
- Java performance improvement from Bryan Varner: Scoped the
receiving byte buffer to the receiver, which cut down on a
lot of time spent allocating short-lived buffers.
- Java performance improvement from Bryan Varner: Added a
constructor for the MessageReceiver to allocate it's buffer
to the same size as the sockets underlying buffer and made
use of the call where possible.
- Added a GetObjectClassName() method to the ObjectPool class.
- The GetNetworkInterfaceInfos() function now supports a new
bit named GNII_INCLUDE_UNADDRESSED_INTERFACES, which tells
it to return even network interfaces with no IP address.
- The default value of the (includeBits) argument to
GetNetworkInterfaceInfos() is now GNII_INCLUDE_ALL_ADDRESSED_INTERFACES
rather than GNII_INCLUDE_ALL_INTERFACES, to reflect the nuance
that was added above; the default behavior is unchanged, though.
- When -DMUSCLE_USE_CPLUSPLUS11 is defined, muscleMin() and
muscleMax() now use variadic templates so that they can
accept any number of arguments (rather than just up to five).
o Java fix from Bryan Varner: Updated the handling code for
NotEnoughDataExceptions to no longer rely on the position of
the buffer (but rather look at the buffer limit, or the amount
previously read into the buffer) -- which basically makes the
above change unnecessary, but I'm paranoid.
o Changed the Message, Queue, Hashtable, and String classes so
that when they are set equal to an empty/default object, they
now free any large dynamically-allocated buffer they may be holding.
This avoids excessive memory usage by objects that have been
returned to an ObjectPool after being used to hold large amounts
of data.
o Modified muscleMin(), muscleMax(), muscleSgn(), muscleClamp(),
and musclAbs() to take arguments and return by value rather
than by const-reference.
* Java fix from Bryan Varner: Fixed a bug causing communication
failures in the NIO message unflattening.
* Java fix from Bryan Varner: Prior to throwing a
NotEnoughDataException the position of the buffer wasn't
being updated in MessageIOGateway and JZLibMessageIOGateway.
6.06 Released 8/15/2014
- ParseHumanReadableTimeIntervalString() can now parse strings
where only the time-unit is specified. (e.g. "second" now
returns 1000000)
- Added GetInternalThreadPulseTime(), InternalThreadPulse(),
WriteToMainThread(), and ShutdownInternalThread() methods
to the AsyncDataIO class, so that it can be subclassed for
use in impersonating a "live" socket, using test data
internally generated inside its I/O thread.
o Added code to testbytebuffer.cpp, so that if a filename is
passed as an argument, the contents of the specified file
will be printed to stdout in annotated-hex format.
o Added support for a -DMUSCLE_AVOID_XENOMAI flag, to be used
when compiling with -DTARGET_PLATFORM_XENOMAI but we don't
want MUSCLE to use Xenomai anyway.
* Merged in Augustin Cavalier's patch to get MUSCLE to
compile again under Haiku.
* Modified the Queue code to avoid a static-analyizer warning.
* Fixed a valgrind hit in AbstractReflectSession::Reconnect().
* Fixed a bug in AsyncDataIO that would cause it to hang
when being shut down.
* Fixed a bug that could cause a QueryFilter's replacement
ConstMessageRef object to be ignored in certain circumstances.
6.05 Released 6/27/2014
- Upgraded the captive zlib implementation to v1.2.8.
o Moved public repository from FreeCode to GitHub, because
FreeCode no longer accepts release announcements.
o Renamed LICENSE.txt to LICENSE, since that's how GitHub
likes the license file to be named.
* Merged in Mika Lindqvist's patch to avoid some truncation
warnings for strlen() calls under 64-bit Visual C++.
6.04 Released 6/11/2014
- Added a public GetParametersConst() method to the
StorageReflectSession, for easier debugging.
* Fixed a bug that prevented the PR_COMMAND_REMOVEPARAMETERS
handler from removing parameters that had escaped wildcard
characters in their names.
6.03 Released 6/2/2014
- Added a convenience method muscleArrayIndexIsValid() that
returns true iff the specified numeric index is a valid index
into the specified array.
- Added a CloseCurrentLogFile() function that can be used to
force the file-logger to close any log file that it currently
has open.
- Added a SetSendDestinations() method to the UDPSocketDataIO
class, for convenience.
- The Launch*() and System*() methods in the ChildProcessDataIO
class now take an optional directory-path argument so that you
can specify the current working directory of the child process.
- Added move-constructors and move-assignment operators to the
Ref and ConstRef classes (available only when
MUSCLE_USE_CPLUSPLUS11 is defined, of course).
- Added a Reset() method to the PointerAndBool class.
- Added a SwapContents() method to the PointerAndBool class.
- Added RemoveHeadMulti() and RemoveTailMulti() convenience
methods to the Queue class.
o Queue::GetArrayPointer() now makes sure to set (retLength)
to 0 when it returns NULL.
* Under Windows, GetConstSocketRefFromPool() now automatically
sets the don't-inherit flag on any sockets passed to it. This
avoids problems caused by child processes unintionally holding
sockets connections open in the parent process.
* Fixed a bug in Queue::EnsureSizeAux() that would cause a
bogus extra item to be added to the end of the Queue if the
(setNumItems) argument was set to true.
* The MacOS/X implementation of DetectNetworkConfigChangesSession
would fail to notify its calling code about a changed network
configuration if the network change did not include any
IP address changes. Now it does provide a notification
for that scenario as well.
6.02 Released 4/2/2014
- Added optional (addHeaderBytes) and (addFooterBytes) arguments
to the DeflateByteBuffer() utility functions.
- Added an implementation of GetByteBufferFromPool() that takes
a DataIO as an argument, for easy reading in of files, etc.
- Added a NybbleizeData() implementation that takes a pointer
and length argument rather than a ByteBuffer object.
- Added an AreKeySetsEqual() convenience method to the Hashtable
class. This method checks for equal key-sets while ignoring
the values in the two Hashtables.
- Added WithoutPrefixIgnoreCase() and WithoutSuffixIgnoreCase()
convenience methods to the String class.
- Added some missing convenience overloads for HexBytesToString().
- CanWildcardStringMatchMultipleValues() now ignores dashes in the
string, since they only have meaning when enclosed in brackets --
and if there are brackets in the string, those will be sufficient
to cause CanWildcardStringMatchMultipleValues() to return true.
o Renamed CanRegexStringMatchMultipleValues() to
CanWildcardStringMatchMultipleValues(), as it is really examining
the simplified wild-card syntax and not the official regex
syntax.
o Several locations that were calling HasRegexTokens() to decide
if it was worth doing pattern-matching with a key-string now
call CanWildcardStringMatchMultipleValues() instead.
o DataNode::Reset() now deletes any metadata structures the
DataNode may have accumulated, rather than simply clearing them.
This saves RAM, and also ensures that recycled DataNodes will
act exactly the same as newly created ones.
* The MemMem() function did not return correct results in all
cases. Rewrote it to work correctly.
6.01 Released 1/7/2014
- Added a PrependWord() convenience method to the String class.
- Added WithReplacements() convenience methods to the String class.
- Added a SetExplicitDelayMicros() method to the
DetectNetworkConfigChangesSession class.
- Added a IsCopperDetected() method to the NetworkInterfaceInfo
class, so that code can tell whether or not a Ethernet jack
has a cable plugged in to it.
- Added a "quietsend" argument to hexterm.
o The NetworkInterfacesChanged() virtual method
in the DetectNetworkConfigChangesSession class
has been changed to take an argument that calls out
which network interfaces in particular have changed.
This functionality is currently only implemented under
Linux, MacOS/X and Windows. For other OS's the
argument will always be an empty list.
* Fixed a bug in the Linux implementation of
DetectNetworkConfigChangesSession that could cause
a segmentation fault if recvmsg() returned an error
(e.g. due to a signal being received).
6.00 Released 10/14/2013
- Rewrote the SSLSocketDataIO class to work better
with non-blocking I/O (in conjunction with the
new SSLSocketAdapterGateway class).
- Added implementations of SSLSocketDataIO::SetPrivateKey()
and SSLSocketDataIO::SetCertificate() that take a
ByteBuffer as an argument.
- Added an SSLSocketAdapterGateway class that is used
to manage OpenSSL's internal state machine when using
an SSLSocketDataIO class with your gateway.
- Added SetSSLPrivateKey() and GetSSLPrivateKey() methods
to the ReflectServer class, for easier enabling of SSL
authentication on all incoming TCP connections. These
methods are available iff MUSCLE_ENABLE_SSL is defined.
- Added SetSSLPublicKeyCertificate() and GetSSLPublicKeyCertificate()
methods to the ReflectServer class, for easier enabling
of SSL authentication on outgoing TCP connections. These
methods are available iff MUSCLE_ENABLE_SSL is defined.
- Added SetSSLPrivateKey() and SetSSLPublicKeyCertificate()
methods to the MessageTransceiverThread class, for easier
enabling of SSL functionality when using threaded I/O.
- Added an ssl_data folder with some info on generating
OpenSSL public/private keypairs, and an example keypair
for use in testing OpenSSL.
- When MUSCLE_ENABLE_SSL is defined, muscled now accepts
an optional 'privatekey=filename' argument. When specified,
SSL mode will be enabled and muscled will only accept incoming
TCP connections that present public keys that match this
private key/certificate.
- When MUSCLE_ENABLE_SSL is defined, portablereflectclient
and qt_example will now accept an optional
'publickey=filename' argument. When specified, SSL mode
will be enabled and these clients will connect to muscled
using OpenSSL and present this file as their credentials.
- Added an "Animate" checkbox to the qt_example demo.
Checking it causes the window to move its indicator around
automatically. This is fun and also useful if you want to
test a scenario where multiple clients are generating traffic
simultaneously.
- Made the qt_example demo prettier.
- Renamed the C++11-helper macros in Hashtable.h and Queue.h
to make them less likely to collide with other packages' macros.
* Fixed some minor errors in the SSLSocketDataIO class.
o Renamed SSLSocketDataIO::SetKey() to SetPrivateKey().
o Renamed SSLSocketDataIO::SetCertificate() to
SetPublicKeyCertificate().
o AbstractMessageIOGateway::SetDataIO() is now a virtual
method.
[For history information about older releases, see the HISTORY.txt file in the muscle archive]