MUSCLE Changelog

What's new in MUSCLE 6.41

Mar 27, 2017
  • Added ReadAndDeflateAndWrite() and ReadAndInflateAndWrite() functions to the ZLibUtilityFunctions.{cpp,h} API, and to the ZLibCodec class, to more easily support inflation/ deflation of large files without having to load all their data into RAM at once.
  • Added Visual Studio 2017 RTM project files, as provided by Mika Lindqvist.
  • FileDataIO::GetReadSelectSocket() and GetWriteSelectSocket() now return valid ConstSocketRef objects on OS's that do support select-ing on a file's file descriptor (read: under POSIX-y OS's, but not under Windows)
  • hexterm now supports a file=filename argument, in case you want hexterm to read its input bytes from a file.
  • Fixed a number of DOxygen-commenting oversights detected by Alvaro Lopez Ortega's "doxy-coverage" comment-checking tool.
  • Tweaked some of the serialization/deserialization code to be more careful about avoiding non-aligned word accesses.
  • Changed the "OUT OF MEMORY" error message produced by WARN_OUT_OF_MEMORY macro to read "MEMORY ALLOCATION FAILURE" instead (since these errors can be caused by a corrupted heap as well as by actual memory exhaustion)

New in MUSCLE 6.40 (Mar 5, 2017)

  • Added templated constructors to the Ref and ConstRef classes so that it is now possible to do implicit upcasting when creating or assigning a Ref or ConstRef object (e.g. DataIORef x = TCPSocketDataIORef(y))
  • Added DECLARE_REFTYPES macros to the declarations of all classes that are subclasses of RefCountable, for convenience.
  • Integrated Mika Lindqvist's patch to qt_muscled.pro so that qt_muscled now includes the necessary zlib files under Windows.
  • Removed explicit Ref-type-casting code from a number of locations where it is no longer necessary.

New in MUSCLE 6.38 (Jan 25, 2017)

  • Added an Atoxll() function; it is the same as Atoull() except that it parses hexadecimal strings into uint64s ather than decimal strings.
  • hexterm now allows you to optionally specify a local port number to bind an otherwise transmit-only udp session to (e.g. "./hexterm udp=127.0.0.1:5555_6666" would send to port 5555 but listen for incoming packets on port 6666)
  • Fixed a bug in MessageField::IsEqualTo() that could cause two Message objects to be considered equivalent to each other when in fact they are different.

New in MUSCLE 6.37 (Oct 19, 2016)

  • Added an AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK for (DataNode *) so that the code will again compile on old (3.x) versions of g++ that don't support SFINAE properly.
  • HandleStandardDaemonArgs() now prints out a list of network interface information if the command line argument "printnetworkinterfaces" is supplied by the user.
  • ParseHexBytes() (and therefore any programs that depend on it, such as hexterm) now understands C-style escaped-control-char conventions, e.g. r means carriage-return, n means newline.
  • Added a work-around for Windows' GetAdaptersAddresses() info returning 255.255.255.255 as the broadcast address for an IPv4 interface. GetNetworkInterfaceInfos() will now detect when this happens and replace that address with the direct broadcast address for the subnet (e.g. 192.168.0.255) instead.

New in MUSCLE 6.36 (Jun 24, 2016)

  • The NetworkInterfaceInfo class now has a GetMACAddress() method that will return the 48-bit MAC address associated with the interface.
  • udpproxy will now join a UDP socket to its multicast group if the provided IP address is a multicast IP address.
  • Added a new function Crash() which does just what it says. The MCRASH macro now calls Crash() after it prints a stack trace.

New in MUSCLE 6.35 (May 27, 2016)

  • Revised MessageIOGateway::DoInputImplementation() so that if a subclass's override of UnflattenHeaderAndMessage() has retained a reference to its scratch-input-buffer, DoInputImplementation() will recognize that and refrain from trying to reuse that buffer as a place to store subsequent incoming Message data.
  • Added Visual Studio 15 project files (Intel and ARM versions), as provided by Mika Lindqvist.
  • Fixed the MuscleQThreadSocketNotifier constructor so that it will compile in conjunction with Qt 4.x.
  • Merged in some ARM compatibility tweaks from Mika Lindqvist.
  • Suppressed some MSVC type-conversion warnings in SetupSystem.cpp

New in MUSCLE 6.34 (Mar 16, 2016)

  • Added GetQThread() accessor methods to the Thread class. These methods are only available when MUSCLE_USE_QT_THREADS is defined.
  • Added support for a new preprocessor flag, MUSCLE_ENABLE_QTHREAD_EVENT_LOOP_INTEGRATION. When this flag is defined, the Thread::InternalThreadEntry() will use QThread::exec() as its event loop rather than a simple while(WaitForNextMessageFromOwner()) loop. This allows for better integration with QObjects living inside the thread.
  • Modified the ThreadedInternalSession class in the qt_advanced_example to use a QTimer for its periodic messages when MUSCLE_ENABLE_QTHREAD_EVENT_LOOP_INTEGRATION is defined, rather than calling WaitForNextMessageFromOwner(), just as an example of what can be done with better Qt integration.
  • Replaced the Thread class's writable GetInternalSocketSet() method with a more user-friendly API, including new methods RegisterInternalThreadSocket(), UnregisterInternalThreadSocket(), UnregisterAllInternalThreadSockets(), and IsInternalThreadSocketReady().
  • Replaced the Thread class's writable GetOwnerSocketSet() method with a more user-friendly API, including new methods RegisterOwnerThreadSocket(), UnregisterOwnerThreadSocket(), UnregisterAllOwnerThreadSockets(), and IsOwnerThreadSocketReady().
  • Fixed a potential stack overflow in PlainTextMessageIOGateway:: DoOutputImplementation().
  • Removed some unnecessary "#include " directives from the qt_advanced_example cpp files that were causing the example program not to build under Windows.
  • Added an #ifdef around IPAddressAndPort::WithInterfaceIndex() so that code will again compile if MUSCLE_AVOID_IPV6 is defined.

New in MUSCLE 6.33 (Mar 2, 2016)

  • When MUSCLE_USE_CPLUSPLUS11 is defined, the Queue class no longer bothers resetting values in its internal array to their default state, if ItemType is a trivial type.
  • When MUSCLE_USE_CPLUSPLUS11 is defined, the Hashtable class no longer bothers resetting values in its internal array to their default state, if their type (KeyType or ValueType) is a trivial type.
  • When MUSCLE_USE_CPLUSPLUS11 is defined, the SanitySetupSystem class constructor now does some basic sanity checks on the std::is_trivial() method to make sure it is working as expected.
  • hexterm now prints time-since-previous-received-data whenever it prints incoming data, for easier performance checking.
  • Added GetBuildFlags(), PrintBuildFlags() and LogBuildFlags() functions to SystemInfo.h so that it's easy for a MUSCLE-based executable to report the preprocessor flags it was built with. This can be handy for debugging purposes.
  • muscled now reports its build-flags at startup, if is launched with log level "debug" or higher (e.g. "displaylevel=debug").
  • Added a WithInterfaceIndex() convenience method to the IPAddressAndPort class.
  • Usage of the DetectNetworkConfigChangesSession class has been simplified. In particular, it is no longer necessary to subclass this class in order to use it; instead you can now just have any of your existing session or factory subclasses implement the new INetworkConfigChangesTarget interface, and the DetectNetworkConfigChangesSession will call their INetworkConfigChangesTarget methods when appropriate.
  • The Windows-only "console" command line argument now can take an optional value; e.g. console=foo.txt will cause the program's stdout and stderr output to be redirected to file foo.txt.
  • The Win32AllocateStdioConsole() function now takes an optional argument, as described above.
  • hexterm now looks for a "nojoin" command line argument when a multicast group is specified; if found, it will deliberately not join the multicast group (and become a send-only UDP session)
  • DetectNetworkConfigChangesSession::SetEnabled(false) now also suppresses calls to ComputerIsAboutSleep() and ComputerJustWokeUp().
  • The DECLARE_REFTYPES macro now specifies the muscle namespace explicitly, to make it easier to use from other namespaces.
  • Fixed an underflow bug in LogHexBytes() and friends that would cause 4 billion dashes to be printed if the title text was too long.
  • hexterm.vcproj now includes the necessary shlwapi.lib dependency

New in MUSCLE 6.32 (Dec 20, 2015)

  • Added support for a new compiler flag, -DMUSCLE_RECORD_REFCOUNTABLE_ALLOCATION_LOCATIONS, that makes it easier to track down the cause of RefCountable objects not getting freed properly on process exit. See BUILDOPTIONS.TXT for details.
  • Tweaked SetupSystem.cpp so that using it no longer requires MiscUtilityFunctions.cpp to be compiled also.
  • The _childProcessCrashed flag is now reset by WaitForChildProcessToExit() only when there is a child process handle available to wait on. That way multiple calls to WaitForChildProcessToExit() won't obliterate the child-process-crashed information.
  • Under Windows, the default handled-signals set now also includes CTRL_C_EVENT and CTRL_BREAK_EVENT, so that when running "muscled.exe catchsignals", these keystrokes can also be used to cleanly shut down the muscled process.

New in MUSCLE 6.31 (Aug 28, 2015)

  • The ChildProcessDataIO class now has a DidChildProcessCrash() method that will return true iff WaitForChildProcessToExit() detected that the child process exited due to an unhandled signal rather than via a normal process termination.
  • In v6.30, the windows implementation of ChildProcessDataIO would always hide the child process's windows, even in cases where it was desirable for the child process's windows to be visible. To avoid that misbehavior, the child process's windows are now hidden only if the CHILD_PROCESS_LAUNCH_BIT_WIN32_HIDE_GUI bit is set in the (launchBits) argument.
  • Some of the the DOxygen comments for enumerations in the header files were not formed correctly, so the DOxygen HTML pages would leave them undocumented. Fixed.
  • Fixed a compiler warning in MessageField::IsEqualTo().

New in MUSCLE 6.30 (Aug 13, 2015)

  • The Message class now uses special-case variant logic for fields that contain only a single value, so that in the common case the allocation of an AbstractDataArray object is avoided.
  • Added a convenience overload of GetMessageFromPool() that takes a ByteBufferRef as its argument.
  • Merged in Mika's patch to fix the _sntprintf_s() calls in the Windows implementation of SysLog.cpp.
  • DetectNetworkConfigChanges.cpp would fail to compile under Windows under some circumstances, due to unicode-string handling issues. Fixed.
  • Added spaces to *_FORMAT_SPEC tokens in dataio/RS232DataIO.cpp
  • Added missing namespace qualifiers to MCRASH() macro, so that it can be called from another namespace.
  • Fixed a bug in the Hashtable class that could cause crashes after a call to EnsureSize(0, true).
  • Message::Unflatten() now resizes the Message's entries-Hashtable to be the exact size of the number of entries it will contain.
  • Added some #includes to the gz*.c zlib files so "implicit function declaration" warnings are no longer emitted when compiling under MacOS/X.
  • Fixed a static-initialization-ordering bug in the ObjectCounterBase class that could cause it to try and lock an invalid Mutex during process startup or shutdown.
  • Under Windows, use of the ChildProcessDataIO class could cause an empty Console window to appear. That no longer happens.

New in MUSCLE 6.23 (Jul 9, 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.
  • 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.
  • 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.

New in MUSCLE 6.22 (Jun 12, 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.
  • Added some more Cygwin/MinGW compatibility changes contributed by Mika Lindqvist.
  • 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.

New in MUSCLE 6.21 (May 15, 2015)

  • Merged in Mika Lindqvist's patch to make the StackWalker code use less stack space.
  • 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.
  • Modified the Windows implementation of GetNetworkInterfaceInfos() to not specify an interface index for IPv6 network device address, as doing so causes UDP-packet-routing problems under Windows 7.

New in MUSCLE 6.20 (Apr 25, 2015)

  • Added a new sub-folder besupport/admin_gui. It contains Fredrik Modeen's GUI shell for more easily running muscledunder 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 ca 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)
  • Renamed the vc++ subfolder to vc++8 to make it more obvious that the project files it contains are for Visual Studio 2008.
  • 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.
  • 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.
  • 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".
  • Replaced various of the aforementioned calls with their muscle*() equivalents in the codebase.
  • Merged in some patches contributed by Mika Linqvist to avoid CRT security warnings when compiling under MSVC 2013.
  • 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.
  • Modified DefaultFileLogger::CloseLogFile() to reduce its stack usage.
  • 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.

New in MUSCLE 6.12 (Apr 7, 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).
  • Added a NotCopyable base class to various classes (Socket, DataNode, AbstractReflectSession, etc) so that the compiler will verify that they are not being copied.
  • 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)
  • 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.

New in MUSCLE 6.11 (Feb 3, 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.
  • MutexGuard's argument is now a const reference, since Mutex::Lock() and Mutex::Unlock() are const methods.
  • 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.
  • 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.

New in MUSCLE 6.10 (Dec 13, 2014)

  • The DetectNetworkConfigChangesSession class now has ComputerIsAboutToSleep() and puterJustWokeUp() callback methods that are called at the times indicated by their names. Currently this functionality is implemented only under MacOS/X and Windows.
  • Added work-arounds for gcc-3.x SFINAE incompatibilities to MuscleSupport.h
  • 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.

New in MUSCLE 6.09 (Nov 4, 2014)

  • Changes:
  • 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.
  • 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.
  • 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)
  • 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.

New in MUSCLE 6.08 (Oct 16, 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.
  • 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.

New in MUSCLE 6.07 (Sep 19, 2014)

  • New Feature: Added a GlobalPrintRecyclersToStream() method to the AbstractObjectRecycler class, for better debugging and analysis of the ObjectPool's memory usage.
  • New Feature: Added an abstract PrintToStream() method to the AbstactObjectRecycler class, and a concrete implementation of that method to the ObjectPool and ThreadPool classes.
  • New Feature: Added a testobjectpool.cpp test program to the tests folder, as a quick sanity check for the ObjectPool class.
  • New Feature: 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.
  • New Feature: 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.
  • New Feature: 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.
  • New Feature: Added a GetObjectClassName() method to the ObjectPool class.
  • New Feature: 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.
  • New Feature: 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.
  • New Feature: 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).
  • Other: 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.
  • Other: 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.
  • Other: Modified muscleMin(), muscleMax(), muscleSgn(), muscleClamp(), and musclAbs() to take arguments and return by value rather than by const-reference.
  • Bug Fixed: Java fix from Bryan Varner: Fixed a bug causing communication failures in the NIO message unflattening.
  • Bug Fixed: Java fix from Bryan Varner: Prior to throwing a NotEnoughDataException the position of the buffer wasn't being updated in MessageIOGateway and JZLibMessageIOGateway.

New in MUSCLE 6.06 (Aug 16, 2014)

  • New: ParseHumanReadableTimeIntervalString() can now parse strings where only the time-unit is specified. (e.g. "second" now returns 1000000)
  • New: 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.
  • Changes: 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.
  • Changes: 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.
  • Bug Fix: Merged in Augustin Cavalier's patch to get MUSCLE to compile again under Haiku.
  • Bug Fix: Modified the Queue code to avoid a static-analyizer warning.
  • Bug Fix: Fixed a valgrind hit in AbstractReflectSession::Reconnect().
  • Bug Fix: Fixed a bug in AsyncDataIO that would cause it to hang when being shut down.
  • Bug Fix: Fixed a bug that could cause a QueryFilter's replacement ConstMessageRef object to be ignored in certain circumstances.

New in MUSCLE 6.05 (Jun 28, 2014)

  • New:
  • Upgraded the captive zlib implementation to v1.2.8.
  • Bug fix:
  • Merged in Mika Lindqvist's patch to avoid some truncation warnings for strlen() calls under 64-bit Visual C++.
  • Moved public repository from FreeCode to GitHub, because FreeCode no longer accepts release announcements.
  • Renamed LICENSE.txt to LICENSE, since that's how GitHub likes the license file to be named.

New in MUSCLE 6.04 (Jun 12, 2014)

  • New feature:
  • Added a public GetParametersConst() method to the StorageReflectSession, for easier debugging.
  • Bug fix:
  • Fixed a bug that prevented the PR_COMMAND_REMOVEPARAMETERS handler from removing parameters that had escaped wildcard characters in their names.

New in MUSCLE 6.03 (Jun 3, 2014)

  • New Feature:
  • 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.
  • Other:
  • Queue::GetArrayPointer() now makes sure to set (retLength) to 0 when it returns NULL.
  • Bug Fix:
  • 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.

New in MUSCLE 6.02 (Apr 3, 2014)

  • New feature: Added optional (addHeaderBytes) and (addFooterBytes) arguments tOther: the DeflateByteBuffer() utility functions.
  • New feature: Added an implementation of GetByteBufferFromPool() that takes a DataIOther: as an argument, for easy reading in of files, etc.
  • New feature: Added a NybbleizeData() implementation that takes a pointer and length argument rather than a ByteBuffer object.
  • New feature: Added an AreKeySetsEqual() convenience method tOther: the Hashtable class. This method checks for equal key-sets while ignoring the values in the twOther: Hashtables.
  • New feature: Added WithoutPrefixIgnoreCase() and WithoutSuffixIgnoreCase() convenience methods tOther: the String class.
  • New feature: Added some missing convenience overloads for HexBytesToString().
  • New feature: CanWildcardStringMatchMultipleValues() now ignores dashes in the string, since they only have meaning when enclosed in brackets -New feature: and if there are brackets in the string, those will be sufficient tOther: cause CanWildcardStringMatchMultipleValues() tOther: return true.
  • Other: Renamed CanRegexStringMatchMultipleValues() tOther: CanWildcardStringMatchMultipleValues(), as it is really examining the simplified wild-card syntax and not the official regex syntax.
  • Other: Several locations that were calling HasRegexTokens() tOther: decide if it was worth doing pattern-matching with a key-string now call CanWildcardStringMatchMultipleValues() instead.
  • Other: DataNode::Reset() now deletes any metadata structures the DataNode may have accumulated, rather than simply clearing them. This saves RAM, and alsOther: ensures that recycled DataNodes will act exactly the same as newly created ones.
  • Bug fixed: The MemMem() function did not return correct results in all cases. Rewrote it tOther: work correctly.

New in MUSCLE 6.01 (Jan 9, 2014)

  • New feature:
  • 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.
  • 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.

New in MUSCLE 6.00 (Oct 16, 2013)

  • New feature: Rewrote the SSLSocketDataIO class to work better with non-blocking I/O (in conjunction with the new SSLSocketAdapterGateway class).
  • New feature: Added implementations of SSLSocketDataIO::SetPrivateKey() and SSLSocketDataIO::SetCertificate() that take a ByteBuffer as an argument.
  • New feature: Added an SSLSocketAdapterGateway class that is used to manage OpenSSL's internal state machine when using an SSLSocketDataIO class with your gateway.
  • New feature: 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.
  • New feature: 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.
  • New feature: Added SetSSLPrivateKey() and SetSSLPublicKeyCertificate() methods to the MessageTransceiverThread class, for easier enabling of SSL functionality when using threaded I/O.
  • New feature: Added an ssl_data folder with some info on generating OpenSSL public/private keypairs, and an example keypair for use in testing OpenSSL.
  • New feature: 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.
  • New feature: 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.
  • New feature: 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.
  • New feature: Made the qt_example demo prettier.
  • New feature: Renamed the C++11-helper macros in Hashtable.h and Queue.h to make them less likely to collide with other packages' macros.
  • Bug Fix: Fixed some minor errors in the SSLSocketDataIO class.
  • Other: Renamed SSLSocketDataIO::SetKey() to SetPrivateKey().
  • Other: Renamed SSLSocketDataIO::SetCertificate() to SetPublicKeyCertificate().
  • Other: AbstractMessageIOGateway::SetDataIO() is now a virtual method.

New in MUSCLE 5.92 (Sep 23, 2013)

  • New Feature:Improved support for C++11 move-semantics in the Queue and Hashtable classes (enabled only when -DMUSCLE_USE_CPLUSPLUS11 is defined)
  • New Feature:Added some instrumentation to the String class so I can watch how many times a String object is copied, moved, etc (enabled only when -DMUSCLE_COUNT_STRING_COPY_OPERATIONS is defined)
  • New Feature:Added a PrintAndClearStringCopyCounts() function which will print out the String-operation data collected above.
  • New Feature:Added some SFINAE magic to muscleSwap() so that it will swap by calling SwapContents() when possible, rather than by copying to a temporary object.
  • New Feature:Added an initializer-list constructor and overload of AddTailMulti() to the Queue class (available only when -DMUSCLE_USE_CPLUSPLUS11 is defined, of course)
  • Renamed the Queue and array overloads of Queue::AddTail() to AddTailMulti(), to avoid conflicts with the new C++11 template parsing support.
  • Renamed the Queue and array overloads of Queue::AddHead() to AddHeadMulti(), to avoid conflicts with the new C++11 template parsing support.
  • Replaced MCRASH_IMPL macro with a call to assert(false).
  • Bug Fixed:A little more Android-compatibility tweakage.
  • Bug Fixed:Many of the programs in the tests folder weren't compiling under C++11. Fixed.
  • Bug Fixed:Fixed several potential bugs that were detected by clang's static analysis tool.

New in MUSCLE 5.91 (Sep 4, 2013)

  • New Feature: Added EnsureCanPut() convenience method to the Hashtable class.
  • New Feature: Added EnsureCanAdd() convenience method to the Queue class.
  • Changed DoMutexAtomicIncrement() to be an inline function to make calling it more efficient.
  • Bug fixed: Changed QMessageTransceiverThread and QAcceptSocketsThread to call QCoreApplication::postEvent() rather than QApplication::postEvent(), to allow for nonNew Feature: GUI Qt apps.
  • Bug fixed: Updated the Beginner's Guide document to reflect MUSCLE's improved UDP support.
  • Bug fixed: Merged in some Android compatibility changes provided by JeanNew Feature: François Mullet.
  • Bug fixed: Use of the MUSCLE_USE_MUTEXES_FOR_ATOMIC_OPERATIONS compile flag would cause MUSCLE to crash on startup due to an orderNew Feature: ofNew Feature: operations issue. This has been fixed now.
  • Bug fixed: The MUSCLE_USE_MUTEXES_FOR_ATOMIC_OPERATIONS compile flag was previously only used if no other implementation of AtomicCounter was available. Now the flag has higher precedence, so setting the flag means that Mutexes will be used, even if another (more efficient) mechanism is available.

New in MUSCLE 5.90 (Aug 7, 2013)

  • Added a GetPacketMaximumSize() method to the DataIO class to allow gateway code to more intelligently handle UDP-style packetized communication.
  • MessageIOGateway now works usefully in conjunction with UDPSocketDataIO.
  • Added CreateObjectFromArchiveMessage() templated functions to Message.h, to serve as a restoring-side counterpart to GetArchiveMessageFromPool(), etc.
  • AtomicCounter::AtomicIncrement() now returns a boolean (true iff the new counter value is equal to one).
  • Modified the HashtableIterator class so that read-only Hashtable iterations are now thread-safe even if the HTIT_FLAG_NOREGISTER flag isn't specified.
  • Added a muscle_thread_id class to SetupSystem.h, to properly represent a thread ID in an implementation-neutral fashion.
  • Added a "deadlock" program to the tests folder. This program deliberately risks creating a deadlock, as a way to exercise/demonstrate the deadlockfinder test.
  • Added support for a -DMUSCLE_AVOID_THREAD_SAFE_HASHTABLE_ITERATORS command line flag, for those who would rather avoid the overhead of automatic thread safety and promise to supply HTIT_FLAG_NOREGISTER arguments by hand where necessary.
  • Added an optional LRU lookup cache to the GetHostByName() function, so that it can return more quickly when the same hostnames are getting resolved over and over again.
  • Added a SetHostNameCacheSettings() function that enables and adjusts the LRU lookup cache in GetHostByName().
  • Added support for "dnscache" and "dnscachesize" command line arguments in HandleStandardDaemonArgs(), to allow command-line specification of the LRU lookup cache's behavior.
  • Modified the Hashtable class so that the _iterHead, _iterTail, and _freeHead member values are now uint32s rather than pointers, to reduce memory usage.
  • Removed the ThreadLocalStorage::SetFreeHeldObjectsOnExit() method, and added a boolean argument to its constructor instead, since pthreads don't allow you to change that setting after pthread_key_create() has been called.
  • Moved GetCurrentThreadID() into the muscle_thread_id class as a static member function, and changed it to return a muscle_thread_id object rather than unsigned long.
  • Changed the default hostname for sessions without a known IP address from "" to "_unknown_", as the angle brackets in the former string have a special meaning as of the 5.84 release, and that could interfere with node-path matching in unintended ways.
  • The CalculateChecksum() methods in Message.cpp have been modified to be more robust in detecting data transposition differences.
  • Removed the MUSCLE_USE_QT_FOR_ATOMIC_OPERATIONS support from AtomicCounter.h, since Qt's QAtomicInt class doesn't support the functionality that the AtomicIncrement() method's new return value requires.
  • Removed MessageIOGateway::FlattenMessage() and MessageIOGateway::UnflattenMessage(). Added in their place: MessageIOGateway::FlattenHeaderAndMessage() and MessageIOGateway::UnflattenHeaderAndMessage(). These new methods deal with both the header bytes and the Message body at the same time.
  • Added a udpproxy.vcproj file to the tests folder, to help compile udpproxy under Windows.
  • Message:Flatten() now iterates over the fields in the Message once, instead of twice.
  • GetCurrentThreadID() is now an inline function, since it may now get called often by HashtableIterator.
  • Modified the deadlockfinder code to use Queues instead of Hashtables, since muscle_thread_id can't be used as a Hashtable key type anymore.
  • Fixed testudp.cpp to properly use a MessageIOGateway for its UDP communication.
  • Tweaked the ifdefs in FilePathInfo.cpp a bit more so that statInfo.st_birthtimespec won't be accessed when using MacOS/X SDKs that don't provide it.
  • MessageDataIOGateway no longer tries to Unflatten a Message from a zlib-deflated data buffer that it was unable re-inflate.
  • Fixed a bug in SendDataUDP() that could cause SendDataUDP() to incorrectly return an error when sending to a multicast address using non-blocking mode, and the output buffer was full.

New in MUSCLE 5.85 (Jul 3, 2013)

  • New Features:
  • Added LogTime(MUSCLE_LOG_DEBUG) calls to all the error paths in MessageIOGateway::DoInputImplementation() and Message::Unflatten(), so that it's easier to determine when TCP connections are being aborted due to data corruption.
  • Added a PreviousOperationHadTransientFailure() function, which returns true iff errno is EINTR or ENOBUFS.
  • Specifying spamspersecond=-1 will now cause hexterm to send spam data as fast as possible.
  • Other:
  • SocketMultiplexer.h's MUSCLE_USE_POLL implementation was supplying POLLERR to WSAPoll() but WSAPoll() doesn't support POLLERR so WSAPoll() would return an error when this occurred. Worked around the problem by filtering out POLLERR when compiling under Windows.
  • Bug fixes:
  • Fixed a bug where send() returning ENOBUFS could cause the socket connection to be terminated, even though ENOBUFS is not a fatal condition.
  • SocketMultiplexer.cpp would not compile when MUSCLE_USE_POLL was defined. Fixed.
  • The ZLibCodec::Deflate() method would fail to compress all the data in a very large buffer (e.g. over 42MB). Fixed.

New in MUSCLE 5.84 (Apr 22, 2013)

  • The StringMatcher class's numeric-range syntax has been extended so that you can now specify multiple ranges.
  • For example, "" would match strings "19", "20", "21", "25", "30", "31", [...], and "50".
  • Added GetCurrentTime64ForRunTime64() and GetRunTime64ForCurrenTime64()conversion functions to TimeUtilityFunctions.h.
  • Added a GetDescendant() utility method to the DataNode class.
  • Added C++11 move-constructors and move-assignment-operators to the Hashtable, Queue, String, Message, and ByteBuffer classes.
  • For backwards compatibility with older compilers, this code will only be compiled if -DMUSCLE_USE_CPLUSPLUS11 is specified on the compile line.
  • SharedMemory class will now nerf itself into a non-shared-memory class if -DMUSCLE_FAKE_SHARED_MEMORY is specified.
  • Added a testfilepathinfo test to the tests folder.
  • Updated all copyright notice headers to read 2000-2013 Meyer Sound.
  • Added spaces between macro tokens (e.g. UINT32_FORMAT_SPEC) and string constants (e.g. "Hello") to make C++11 compilers happy.
  • ByteBuffer.cpp had a syntax error that would prevent it from compiling on big-endian hosts.Fixed.
  • MacOS/X only: Replaced deprecated Carbon function calls with Mach equivalents, to avoid deprecation warnings under 10.8.x.

New in MUSCLE 5.82 (Oct 3, 2012)

  • Rewrote the Hashtable class so that it now saves memory by internally using smaller per-slot index values (e.g. uint8 or uint16, rather than uint32) in Hashtables with fewer than 65,535 slots in their HashtableEntry-array.
  • Added support for compiling with -DMUSCLE_AVOID_MINIMIZED_HASHTABLES, which will disable the above optimization (since sometimes you'd rather use more memory and have faster code execution)
  • Fixed ZLibUtilityFunctions.cpp so that it will again build when -DMUSCLE_SINGLE_THREAD_ONLY is defined.

New in MUSCLE 5.81 (Sep 14, 2012)

  • If compiled with -DMUSCLE_ENABLE_DEADLOCK_FINDER, HandleStandardDaemonArgs() will now look for a "deadlockfinder" argument that can be used to force deadlock-prints on or off.
  • Rewrote the ZLibUtilityFunctions.cpp calls to use ThreadLocalStorage rather than shared ZLibCodec objects serialized by Mutexes. This change helps avoids any possibility of deadlocks, and also improves performance because now multiple threads can inflate and/or deflate data in parallel. For systems without a ThreadLocalStorage implementation, the old implementation can still be used as a fallback, by compiling with -DMUSCLE_AVOID_THREAD_LOCAL_STORAGE.
  • The pthreads implementation of the ThreadLocalStorage now uses the destructor-callback feature of pthread_create_key() to ensure that created thread-local-data objects are destroyed in a timely manner (i.e. when their host thread exits, rather than only when the ThreadLocalStorage object destructor runs)
  • ParseHexBytes() no longer treats commas as token-separator characters, that way they can be escaped (by prefixing them with a slash) and entered as ASCII literals.

New in MUSCLE 5.80 (Aug 31, 2012)

  • Added a new "micromessage" folder that contains a C API with functions for constructing and parsing Message data directly to/from its flattened form, with no intermediate representations, flattening/unflattening, or dynamic memory allocation necessary. This API would be appropriate for embedded or other severely constrained environments.
  • Added "testmicro", "microchatclient", and "microreflectclient" programs to the tests folder, to serve as tests and examples for the new MicroMessage and MicroMessageGateway APIs.
  • Added a new constructor to the FilePathInfo class that allows explicit/manual setting of the file info parameters.
  • Added MoveName*() methods to the Message class, so that the iteration order of the fields in the Message can be easily modified.
  • Made String::Flatten(), String::Unflattened(), and String::FlattenedSize() into inline methods.
  • IsMulticastIPAddress() now returns true for IPv6-mapped IPv4 multicast addresses (e.g. ::ffff:239.255.1.2)
  • Fixed a bug in MutexGuard class declaration, private copy-constructor had wrong argument type.
  • Fixed some inaccurate comments in ZipUtilityFunctions.h
  • Fixed the "chatclient" test; it was forgetting to read from stdin.

New in MUSCLE 5.72 (Jun 28, 2012)

  • Added HexBytesToAnnotatedString() functions to the MiscUtilityFunctions API. These are similar to PrintHexBytes(), but they output to a String rather than to a file.
  • ParseHumanReadableTimeIntervalString now correctly parses non-integral values (e.g. "3.5 minutes")
  • Fixed a constant-overflow error in testbytebuffer.cpp
  • Fixed the gcc implementation of MuscleX86SwapInt16(), which would fail to compile under gcc 4.7 on 64 bit targets.
  • Usage of the uintptr typedef no longer causes warnings under MSVC when the /Wp64 compiler flag is specified.
  • Cleaned up some other miscellaneous MSVC warnings.

New in MUSCLE 5.71 (Jun 12, 2012)

  • Added a WasSignalCaught() function to SignalHandlerSession.h. This method will return true iff any SignalHandlerSession ever caught a signal in the current process.
  • Added global SetMainReflectServerCatchSignals() and GetMainReflectServerCatchSignals() functions to SignalHandlerSession.h to allow easy programmatic enabling and disabling of the standard signal handling routines.
  • Added WithPrefix(), WithSuffix(), WithoutPrefix(), and WithoutSuffix() convenience methods to the String class.
  • Added TruncateChars() and TruncateToLength() convenience methods to the String class.
  • Added an StartsWithNumber() convenience method to the String class.
  • Added Append*(), Read*(), and Write*() methods to the ByteBuffer class for easier endian-aware adding and retrieiving of various primitive datatypes from a ByteBuffer's data array.
  • Added a SetDataFlags() and IsEndianSwapEnabled() methods to the ByteBuffer class to help the user specify what data endian-ness logic the ByteBuffer should apply in its Append*(), Read*(), and Write*() method calls.
  • Added a testbytebuffer.cpp test to the tests folder to test the new data adding/retrieval routines.
  • Added a PointerAndBool class that stores a pointer and a boolean using no more space than that of a pointer by itself (unless -DMUSCLE_AVOID_BITSTUFFING is enabled).
  • Renamed MUSCLE_AVOID_REFCOUNT_BITSTUFFING to MUSCLE_AVOID_BITSTUFFING, since bit-stuffing is no longer specific to the RefCount class.

New in MUSCLE 5.70 (May 9, 2012)

  • NodePathMatcher::DoTraversal() now returns the number of DataNodes that the traversal visited.
  • Fixed a bug in Queue::Clear() that would cause it only to reset the first item in the queue rather than all of the items.
  • Range-checking in DenybblizeData was incorrect (it would spuriously reject characters 'G' through 'P'). Fixed.

New in MUSCLE 5.69 (Apr 19, 2012)

  • Made Queue::Clear() a bit more efficient.
  • Exposed the DefaultConsoleLogger and DefaultFileLogger classes in LogCallback.h so they can be re-used elsewhere.
  • Added an Indent() convenience method to the String class.
  • The matching logic in AndOrQueryFilter and NandNotQueryFilter now has additional short-circuit logic for better efficiency.
  • StorageReflectSession::RestoreNodeTreeFromMessage() now has an optional (quiet) argument, which can be used to prevent db-subscription-updates from being triggered when the subtree is installed into the database.
  • Rewrote the String::Arg() methods to take C-native argument types rather than fixed-size types (e.g. int instead of int32) so that explicit typecasting is no longer required to avoid ambiguous-argument-type compile errors that previously could occur under certain compilers.
  • Tweaked the .pro files in the qtsupport folders to make them compatible with Qt 5.0.
  • DenybbleizeData() now returns B_ERROR when passed a string with an invalid (odd) length, rather than causing an assertion failure.
  • Inet_NtoA() now formats IPv4-mapped IPv6 addresses in the IPv4 style, if (preferIPv4Style) is set to true.
  • Merged in more Haiku-compatibility fixes provided by Fredrik.

New in MUSCLE 5.68 (Mar 26, 2012)

  • Added an optional (retPort) argument to GetPeerIPAddress().
  • Added optional "spamspersecond" and "spamsize" arguments to hexterm, so that you can have hexterm automatically generate random output at a specified rate for performance testing.
  • Added a "quietreceive" argument to hexterm so that if you don't want to see a printout of the bytes being received, you don't have to.
  • Added GetDistanceTo() and GetSquaredDistanceTo() methods to the Point class.
  • Privileged-address matching is now done using IPv4-style address strings for IPv4 addresses (even when compiled with IPv6 support enabled), per Lior's request.
  • Merged in some Haiku-compatibility fixes provided by Fredrik Modeen.

New in MUSCLE 5.67 (Feb 4, 2012)

  • Added a AreOutgoingMessagesIndependent() method to the MessageIOGateway class, to allow better control over how outgoing Messages are deflated when zlib-encoding is enabled.
  • Removed some unnecessary data members from certain Message field-object classes, to cut down on memory usage.
  • Added a Queue::GetItemAtUnchecked() method.
  • Added a RemoveName() to the Python Message class.
  • Cleaned up the Python code to avoid pychecker warnings
  • Removed Queue::GetItemPointer(). Use Queue::GetItemAt() instead.
  • BitChord::ToHexString() was broken -- fixed.
  • Queue::GetItemAt() would return a garbage pointer if passed an invalid index. Fixed to return NULL (as documented) instead.
  • Fixed a problem in QSignalHandler and QDataIODevice that could occasionally cause a CPU-spin on shutdown under MacOSX/Lion.

New in MUSCLE 5.66 (Jan 7, 2012)

  • Added a CountedRawDataMessageIOGateway class to RawDataMessageIOGateway.{cpp,h}. This class is the same as its RawDataMessageIOGateway superclass, except that it is instrumented to keep a running count of the number of raw data bytes currently held in its output-queue.
  • Added a CountedMessageIOGateway class to MessageIOGateway.{cpp,h}. This is similar to the CountedRawDataMessageIOGateway class described above, except it tracks Message sizes.
  • Added a PopNextOutgoingMessage() virtual method to the MessageIOGateway class, so that subclasses can override its behavior if necessary.
  • Added EventLoopCycleBegins() and EventLoopCycleEnds() virtual method hooks to the ReflectServer class.
  • AbstractMessageIOGateway::AddOutgoingMessage() is now virtual.
  • Trying to use -DMUSCLE_USE_POLL under Windows without declaring an appropriate value for -DWIN32_WINNT now gives an informative compile-error message rather than the inscrutible errors that would appear previously.
  • Fixed minor bug in kqueue that could cause obsolete entries to remain in the _bits Hashtable.
  • Fixed a bug in the RawDataMessageIOGateway class that would cause it to emit Messages with a what-code of 0 (rather than PR_COMMAND_RAW_DATA) when in immediate-forward mode.

New in MUSCLE 5.65 (Dec 27, 2011)

  • Added experimental support for kqueue under FreeBSD/MacOSX, enabled by defining -DMUSCLE_USE_KQUEUE on the compile line.
  • Added experimental support for epoll under Linux enabled by defining -DMUSCLE_USE_EPOLL on the compile line.
  • Updated testsocketmultiplexer.cpp to make it more useful for gathering performance statistics for the various SocketMultiplexer implementations.

New in MUSCLE 5.64 (Dec 14, 2011)

  • Added a SocketMultiplexer class (util/SocketMultiplexer.{cpp,h}) that acts as an API-agnostic wrapper around select() or poll(), depending on whether MUSCLE_USE_POLL is defined or not.
  • MuscleSupport.h now declares uintptr and ptrdiff types that are guranteed to be the same size as a native pointer.
  • Added a PseudoFlattenable base class to Flatten.h, for subclasses that want to act like Flattenable objects but don't want to incur the memory overhead of actually having virtual methods.
  • Modified all MUSCLE code to use a SocketMultiplexer object rather than calling select() or poll() directly.
  • Added a testsocketmultiplexer.cpp test to the tests folder.
  • RefCount.h now uses uintptr instead of (unsigned long) when doing its pointer-bit-stuffing magic, to avoid pointer-truncation warnings from MSVC.
  • Message::FindFlat() now does the right thing when an object is added to the Message as a FlatCountableRef and then retrieved from the Message by value.

New in MUSCLE 5.63 (Dec 2, 2011)

  • Added a MUSCLE_USE_POLL build option which, if defined, will cause ReflectServer::RunEventLoop() to base its event loop around poll() rather than select(). The benefit of this is that with poll() the FD_SETSIZE limit imposed by select() can be be avoided.
  • Made a number of previously protected methods in the AbstractReflectSession class public.
  • StorageReflectSession::PrintSessionsInfo() and StorageReflectSession::PrintFactoriesInfo() now print additional information about the state of the sessions/factories.
  • The Thread constructor now takes an optional boolean argument, so that you can now create a Thread that doesn't allocate a socket-pair for inter-thread messaging purposes. This is useful when you want to create a lot of Threads but don't need to use socket-based inter-thread signalling and don't want to allocate a lot of sockets.
  • Added a FastClear() method to the Queue class (for when you care more about performance than about having item destructors get called right away).
  • Added a RemoveDuplicateItems() method to the Queue class.
  • Retired the MUSCLE_ENABLE_MULTICAST_API compiler flag, and added MUSCLE_AVOID_MULTICAST_API in its place. (Which is another way of saying that the MUSCLE Multicast API calls are now enabled by default)

New in MUSCLE 5.62 (Nov 3, 2011)

  • Added a CountedObject class that various other MUSCLE classes now subclass from. Subclassing from the CountedObject class allows the application to efficiently keep track of the number of objects allocated of that type, for debugging/monitoring purposes.
  • Added a PrintCountedObjectInfo() function that prints to stdout a report of how many objects of each counted type are currently allocated.
  • Added a GetCountedObjectInfo() function that returns a Hashtable containing all of the current CountedObject counts.
  • Added support for a -DMUSCLE_AVOID_OBJECT_COUNTING compiler definition that will turn the object-counting code into a no-op if you want it disabled.
  • The Python Message.PrintToStream() method now recursively prints sub-Messages by default. It has arguments that can be used to limit the depth of the recursion, if desired.
  • Added XINT64_FORMAT_SPEC macros to MuscleSupport.h.
  • MCRASH now calls __builtin_trap() under gcc/g++, rather than writing to an invalid pointer.
  • Added a GetGlobalObjectForType() function, which is similar to GetDefaultObjectForType() except that the returned reference is not read-only.
  • Merged in Jean-François Mullet's patches to allow MUSCLE to be compiled cleanly under Android.
  • Fixed the code so that it now compiles cleanly under clang++ 2.1.
  • String::AppendWord() no longer appends a separator string if the word to be appended is blank.
  • Added some missing string constant declarations to storage_reflect_constants.py
  • Fixed a bug an exception-string-formation line of message.py
  • Fixed a bug in StorageReflectSession::NodeChanged() that would cause incorrect PR_RESULT_UPDATE updates to be generated for subscribers using QueryFilter objects, if the matches-filter status of the node was changed by the node update.

New in MUSCLE 5.61 (Oct 3, 2011)

  • Added a GetCurrentStackUsage() method to the Thread class.
  • Added a CheckThreadStackUsage() function and CHECK_THREAD_STACK_USAGE Macro to Thread.{cpp,h} to make it easier to determine if and when a Thread is allocating more stack space than it was allowed to allocate.
  • Added a ThreadPool class to the system folder.
  • Added EINTR-proof wrapper functions to NetworkUtilityFunctions.h for recv(), recvfrom(), send(), sendto(), read(), and write(). MUSCLE code now calls the wrapper functions (e.g. recv_ignore_eintr) so that incoming signals won't cause spurious errors to be returned.
  • Added an Arg(const void *) method to the String class, so that Arg() can be used to print out pointer values.
  • Replaced String::AddWord() with String::AppendWord(), which is easier to use and takes an optional separator-string argument.
  • The Point and Rect implementations of String::Arg() were broken; fixed.

New in MUSCLE 5.57 (Sep 17, 2011)

  • Added the following new compile-time constant definitions to NetworkUtilityFunctions.h: MUSCLE_EXPECTED_MTU_SIZE_BYTES, MUSCLE_POTENTIAL_EXTRA_HEADERS_SIZE_BYTES, MUSCLE_IP_HEADER_SIZE_BYTES, MUSCLE_MAX_PAYLOAD_BYTES_PER_UDP_ETHERNET_PACKET These constants (particularly the last one) are useful for deciding how many bytes of data can be added to a UDP packet without risking packet fragmentation.
  • testudp now prints out the values of the above constants when it is run.
  • Added a SetCount() method to the NestCount class.
  • HandleStandardDaemonArgs() now accepts "realtime_rr" or "realtime_fifo" as alternatives to the pre-existing "realtime" keyword, for those who like to specify their scheduling algorithm explicitly.
  • The PacketTunnelIOGateway constructor now uses MUSCLE_MAX_PAYLOAD_BYTES_PER_UDP_ETHERNET_PACKET as its default maxTransferUnit value, rather than hard-coding a magic value of 1500 (which was too large anyway)
  • Fixed a bug that could cause Snooze64(MUSCLE_TIME_NEVER) to return immediately, rather than sleeping forever as intended.
  • GetHumanReadableTimeIntervalString(MUSCLE_TIME_NEVER) now returns "forever", rather than "584,942 years".
  • Fixed warning in DemandConstructedObject == operator.
  • Fixed warning in ZLibCodec destructor.

New in MUSCLE 5.56 (Sep 5, 2011)

  • Added a StorageReflectSession::PrintFactoriesInfo() method to go with the existing PrintSessionsInfo() method.
  • Added InsertItemAtSortedPosition() methods to the Queue class, for convenience in doing insertion-sorting.
  • Added SetSuggestedStackSize() and GetSuggestedStackSize() methods to the Thread class.
  • Added a IsSymLink() method to the FilePathInfo class.
  • Added a qt_muscled folder to the qtsupport sub-directory. The .pro file in this folder builds a version of muscled that runs in a Qt GUI window.
  • Added a "Clone Window" button to the qt_example application, to make quick demonstrations of multiple-client scenarios easier.
  • The qt_example application is now more colorful -- each client gets assigned his own (random) color.
  • Added checks for (sizeof(float)==4) and (sizeof(double)==8) to the SanitySetupSystem constructor.
  • PrintHexBytes() and LogHexBytes() now take a ConstByteBufferRef rather than a ByteBufferRef, since they don't ever need to modify the ByteBuffer they receive.
  • DataNode objects now store their ordered-child index as a Queue of DataNodeRefs rather than a Queue of String pointers. This avoids any possibility of dangling pointers in the index.
  • DataNode::GetIndex() now returns a (Queue *) rather than a (Queue *).
  • DataNode::ReorderChild() now takes a DataNodeRef rather than a reference to a DataNode object.
  • Added util/FilePathInfo.cpp, and Moved the non-trivial FilePathInfo method bodies into it.
  • Made FileDescriptorDataIO.cpp compile (as a no-op) under Windows, to avoid project-file confusion.
  • CPULoadMeter::GetCPULoad() now uses uint64s to store tick counts rather than uint32s, to avoid potential overflows.
  • SysLog.cpp now works around the lack of a declaration for TzSpecifiedLocalTimeToSystemTime() function when compiling under Windows with the Mingw compiler.
  • Made several other tweaks for Mingw32 compatibility.
  • Fixed the qt_muscled.pro to work under Windows.
  • Fixed a bug in the qt_example application that would cause a qt_example client to disconnect and reconnect whenever the server-name field lost focus.

New in MUSCLE 5.55 (Jul 29, 2011)

  • Added a "plain" keyword to hexterm's arguments; useful if you don't want any headers in hexterm's output
  • Made it possible to embed hexterm as part of a larger program.
  • Added Arg() methods to the String class that take a bool, a Point, or a Rect as an argument.
  • Added a ToMixedCase() method to the String class.
  • Added AddWord() methods to the String class.
  • Added HeadWithDefault() and TailWithDefault() methods to the Queue class that take a default-argument parameter.
  • Added a PrintSessionsInfo() method to the StorageReflectSession class, for quick discovery of what sessions are present and how much RAM they are each using.
  • The ObjectPool class now takes the maximum slab size as a template argument, and has an assertion-check to make sure that the resulting objects-per-slab count is small enough to be tracked by a uint16 (i.e. is less than 65536)
  • Fixed a crashing bug in hexterm's ASCII mode.

New in MUSCLE 5.54 (Jun 25, 2011)

  • Added a GetDefaultObjectForType() templated function to MuscleSupport.h. This function returns a reference to a default-constructed static object of the specified type.
  • Added a description of the Hashtable class's feature set to the Hashtable DOxygen documentation.
  • Added a const [] operator to the Hashtable class. The [] operator behaves the same as the GetWithDefault() method.
  • Expanded and enhanced the DOxygen per-class documentation of various classes.
  • Reduced sizeof(Queue), sizeof(Hashtable), and sizeof(ObjectPool) by removing their default-object member items and adding calls to GetDefaultObjectForType() instead.
  • Replaced the various get-default-object convenience methods (GetEmptyString(), GetEmptyMessage(), etc) with inline call-throughs to GetDefaultObjectForType().

New in MUSCLE 5.53 (Jun 17, 2011)

  • Added TarFileWriter.{cpp,h} to the zlib folder. This class allows for quick inline writing of .tar files to disk.
  • Added a MUSCLE_MAY_ALIAS macro to MuscleSupport.h, as an easier way to invoke gcc's __attribute__((__may_alias__)). This macro expands to empty under other compilers.
  • Added a version of the muscleCopyIn() function that returns the copied-in value, for convenience.
  • Added a DemandConstructedObject template (in util/DemandConstructedObject.h) to allow for member variables whose constructors aren't called until the object is actually needed for something.
  • Added a ClearAndFlush() method to the String class, for forcing a String object to free its allocated data.
  • Reduced sizeof(String), by by employing a union to reuse the bytes used for referencing small and large char arrays.
  • Reduced sizeof(Ref) by storing the boolean (doRefCount) value in the least significant bit of the item pointer. (this works because the item pointers are guaranteed to be word-aligned -- if for some reason that guarantee isn't valid for a given environment, the old method can be reinstated by adding -DMUSCLE_AVOID_REFCOUNT_BITSTUFFING to your compiler arguments)
  • Reduced sizeof(DataNode) by making the subscribers table demand-allocated, rather than a member variable.
  • Removed the MUSCLE_CPU_REQUIRES_DATA_ALIGNMENT define, because it is no longer used anywhere.
  • Rewrote the HashtableIterator class to no longer use type-punning trickery, so that g++ versions 4.4.0 and higher no longer complain about strict aliasing being broken.

New in MUSCLE 5.52 (Jun 9, 2011)

  • Added a Tuple::Contains() convenience method.
  • Added a ExecuteSynchronousMessageSend() method to the MessageIOGateway class. This method is similar to ExecuteSynchronousMessageRPCCall(), except that this method will return to the caller as soon as the Message is sent, without waiting for the server to return a reply Message.
  • Added CreateSynchronousPingMessage() and IsSynchronousPongMessage() hook methods to the MessageIOGateway class, so that subclasses can specify alternative ping/pong Messages if they wish to.
  • Added a IsCharInLocalArray() method to the String class.
  • Added a IsItemLocatedInThisContainer() method to the Queue class.
  • Added a GetNumUnusedItemSlots() method to the Queue class.
  • Added a + operator and += operators for the ByteBuffer class.
  • Made the + operators for the String class more efficient.
  • Converted the ExecuteSynchronousMessageRPCCall() functions into a method of the MessageIOGateway class, so that its behavior can be used in conjunction with a MessageIOGateway subclass to customize their behavior, if necessary.
  • Some of the methods in the Queue class could access freed memory if passed in references to held data items, and a reallocation occurred. Fixed.
  • Some of the methods in the String class could access freed memory if passed in references to their own string, and a reallocation occurred. Fixed.
  • Some of the methods in the ByteBuffer class could access freed memory if passed in a pointer to their own bytes, and a reallocation occurred. Fixed.
  • Fixed a bug in StorageReflectSession::NodePathMatcher::CheckChildForTraversal() that could cause the traversal callback to be called with an invalid DataNode, likely causing the callback to crash. This bug was a regression introduced in the 5.51 release.
  • CalculateChecksumForFloat() and CalculateChecksumForDouble() would return different checksum values for 0.0 and -0.0, even though the == operator considers them equivalent. Fixed.

New in MUSCLE 5.51 (May 24, 2011)

  • Added convenience methods to the Queue class: HeadWithDefault(), TailWithDefault(), RemoveHeadWithDefault(), RemoveTailWithDefault(), and RemoveItemAtWithDefault(). These methods are all safe to call even when the Queue is empty.
  • Added a SLIPFramedDataMessageIOGateway class to the iogateway folder. As the name suggests, it is used to do SLIP encoding and decoding on outgoing and incoming raw data, respectively.
  • Added an AppendByte() method to the ByteBuffer class, for convenience.
  • The WARN_OUT_OF_MEMORY macro now prints the number of bytes that the failed memory allocation attempted to allocate.
  • Added SetExpendable() and IsExpendable() methods to the AbstractReflectSession class, to help influence which sessions will be thrown under the bus in a low-memory situation.
  • The QueryFilter::Matches() methods have been modified to take a (ConstMessageRef &) argument instead of (const Message &), so that it is now possible to create a QueryFilter subclass that modifies the data it returns. (Not that any of the QueryFilter subclasses included in the MUSCLE distribution currently do this)
  • Removed the optional MemoryAllocator pointer argument from the ReflectServer constructor. Now ReflectServer simply accesses the installed MemoryAllocator object directly (via GetCPlusPlusGlobalMemoryAllocator()) when necessary.
  • When MUSCLE_USE_IPV6 is defined, SharedFilterSessionFactory now compares ip_address objects using ip_address::EqualsIgnoreInterfaceIndex() instead of the == operator. This avoids spurious mismatches between IPv4 addresses that have their interface index set, and those that don't.
  • UnparseArgs(const Message &) wasn't escaping quote marks embedded in the strings in the Message. Fixed.
  • UnparseArgs(const Message &) wasn't properly handling multiple values filed under the same field name. Fixed.

New in MUSCLE 5.43 (Mar 30, 2011)

  • Added GetSocketBlockingEnabled() function to NetworkUtilityFunctions.{cpp,h}
  • Added GetSocketNaglesAlgorithmEnabled() function to NetworkUtilityFunctions.{cpp,h}
  • Added GetSocketSendBufferSize() function to NetworkUtilityFunctions.{cpp,h}
  • Added GetSocketReceiveBufferSize() function to NetworkUtilityFunctions.{cpp,h}
  • Added GetUDPSocketBroadcastEnabled() function to NetworkUtilityFunctions.{cpp,h}
  • hexterm now batches its stdin input together to send in fewer buffers, if possible.
  • Added a libmuscle.a target to the Makefile in the server folder.
  • Directory::MakeDirectory() now takes an optional third argument to specify whether the pre-existence of the requested directory should be considered an error.
  • Added a qt_example sub-directory to the qtsupport folder. This directory contains buildable code for a sample Qt-based GUI MUSCLE client.
  • FilePathInfo now handles file paths ending in a slash properly, even if the filesystem object located at that path is not a directory.
  • Fixed hexterm so that it no longer exits prematurely when reading stdin from a file.
  • ChildProcessDataIO::System(const Queue &) wasn't declared static. Fixed.

New in MUSCLE 5.42 (Feb 28, 2011)

  • Added SetEnabled() and IsEnabled() methods to the DetectNetworkConfigChangesSession class.
  • Removed the ability to set String objects using an argument of type 'char', because having it was preventing the compiler from catching errors where an integer is assigned to a String. Use s = String(&c, 1) instead.
  • The SharedMemory wasn't interpreting the return value of shmat() calls correctly. Fixed.
  • Fixed the access privileges of the Hashtable classes so that they now compile under g++ 4.4.x.

New in MUSCLE 5.41 (Feb 3, 2011)

  • Added a ParseBool() function to MiscUtilityFunctions.{cpp,h}
  • Added convenience implementations of PrintHexBytes() and LogHexBytes() that accept ByteBuffers and ByteBufferRefs.
  • PrintHexBytes() and LogHexBytes() can now gracefully accept NULL pointers without crashing (they will just print out "NULL buffer" instead of any hex bytes)
  • printsourcelocations now filters out commented-out calls to LogTime().
  • Hashtable.h now declares a Void class that can be used as a placeholder for Hashtables that need only keys, not values.
  • Added a PutWithDefault() method to the Hashtable class.
  • Added a CanRegexStringMatchMultipleValues() function to StringMatcher.cpp.
  • Added CaseInsensitiveNumericAwareStringCompareFunctor and NumericAwareStringCompareFunctor classes to String.h
  • printsourcelocations now sorts its output by key before emitting it.
  • Added \r and \n to the list of characters that StringTokenizer will treat as word-separators by default.
  • PrintHexBytes() and LogHexBytes() were incorrectly writing some of their decorative output to stdout, instead of to the specified FILE stream. Fixed.
  • Added some #ifdefs to hexterm.cpp and some logic to the tests Makefile so that when hexterm is built as part of a Meyer software release, it will show the standard Meyer software version string.
  • ReflectServer::DisconnectSession() now calls ShutdownIOFor() on the disconnected session, even if the session is to become a lame duck. That way TCP connections are guaranteed to be disconnected quickly.
  • PulseNode::GetCycleStartTime() now returns the correct value even for PulseNodes that are children of other PulseNodes.
  • Hashtable now uses == operator on user-values, not the != operator.
  • The Hashtable class's Get(key), GetFirstValue(), and GetLastValue() methods were not properly enforcing const-correctness. Fixed.

New in MUSCLE 5.35 (Dec 6, 2010)

  • Added a MoveToPosition(key, idx) method to the Hashtable class.
  • Added a InsertOrderedChildNode() utility method to the StorageReflectSession class.
  • hexterm now includes a version number in its LogUsage() text.
  • ChildProcessDataIO::Launch*() can now be told to only capture output to stderr, or stdout
  • Added a GetTotalDataSize() method to the ObjectPool class.
  • Added a GetNumAllocatedItemSlots() method to the ObjectPool class.
  • Changed QueryFilterRef arguments to ConstQueryFilterRef where appropriate.
  • Replaced the (usePty) boolean in ChildProcessDataIO::Launch*() method with a launchBits bit-chord, so that multiple options can be specified.
  • Renamed Hashtable::GetNumAllocatedSlots() to GetNumAllocatedItemSlots().
  • GetSystemMemoryUsagePercentage() was not being calculated accurately under MacOS/X. Fixed.
  • ZLibUtilityFunctions.cpp now installs a cleanup-callback when necessary, so that any privately allocated ZLibCodec objects will be deleted as part of the shutdown sequence and thus won't show up in valgrind as possibly-leaked-memory anymore.
  • ByteBuffer::SetBuffer() now deallocates the current buffer if the new data size is less than half of the current data size, to avoid wasting memory.

New in MUSCLE 5.34 (Oct 20, 2010)

  • Added an optional (maxAsyncConnectPeriod) argument to the AddNewConnectSession() and AddNewDormantConnectSession() methods of the AbstractReflectSession and MessageTransceiverThread classes.
  • Added SetMaxAsyncConnectPeriod() and GetMaxAsyncConnectPeriod() methods to the AbstractReflectSession class.
  • Added an optional MUSCLE_MAX_ASYNC_CONNECT_DELAY_MICROSECONDS constant to the set of compiler -D flags that the muscle code looks for during compilation.
  • Added Strcasecmp() and Strncasecmp() wrapper functions to MiscUtilities.h, to hide Windows' inconsistent function names.
  • muscled and the programs in the tests folder are now compiled with the -DMUSCLE_USE_IPV6 flag enabled.
  • Added support for "disablestdout" and "disablestderr" startup arguments, that cause the program to close its STDOUT_FILENO and STDERR_FILENO files, respectively (and thus suppress its output from then on)
  • DebugTimer can now accept a negative logLevel paramter, which will force it to output using printf() instead of LogTime().
  • Added a GetSystemMemoryUsagePercentage() function to MiscUtilityFunctions.{cpp,h}

New in MUSCLE 5.33 (Sep 1, 2010)

  • Added an optional (argIdx) argument to ParseConnectArg() and ParsePortArg() in MiscUtilityFunctions.{cpp,h}
  • Added a udpproxy program to the tests folder. This can be used to forward UDP packets to and from a further destination.
  • Added a NumericAwareStrcasecmp() function to String.{cpp,h}.
  • Added NumericAwareCompareTo() and NumericAwareCompareToIgnoreCase() methods to the String class.
  • Added SetMask() and GetMask() methods to the NumericQueryFilter class, to allow bitfield masking all numeric QueryFilters.
  • Added a printtypecode program to the test folder, for quickly getting the ASCII representation of a 32-bit type code.
  • Changed String::CompareToIgnoreCase() to call strcasecmp() rather than calling ToUpper() on both strings.
  • Removed the OP_CONTAINS_BITS and OP_DOESNT_CONTAIN_BITS operators from the NumericQueryFilter class, as that functionality can now be handled more generally via the SetMask() call instead.
  • Inet_PtoN now sets the ai_flags value to AI_NUMERICHOST under Windows, so that non-numeric address strings (e.g. "") are no longer possibly misinterpreted as valid IP addres strings.
  • ParseArgs() now un-escapes any escaped quote marks.
  • The micromuscle Java classes were still packaged under com.lcs.*. Changed them to com.meyer.*

New in MUSCLE 5.32 (Jul 23, 2010)

  • Added a GetTimeStampForHumanReadableTimeValues() function to SysLog.{cpp,h}. This function does the inverse operation of GetHumanReadableTimeValues().
  • Added a HumanReadableTimeValues::ToString() method, for convenience.
  • Added SetFSyncOnClose() and IsFSyncOnClose() methods to the FileDescriptorDataIO class.
  • Added a SortFieldNames() method to the Message class.
  • Added FindMatchingNode() and FindMatchingNodes() convenience methods to the StorageReflectSession class.
  • Added a serialproxy utility to the tests folder. This program exports a local serial port as a TCP port.
  • Message::FieldsAreSubsetOf() is now a public method.
  • Replaced GetServerUptime() with GetServerStartTime(), so that the returned value can remain meaningful even if stored for a period of time.
  • Threads in a Java com.meyer.muscle.thread.ThreadPool object now exit cleanly when they are interrupted (e.g. by an applet shutdown). Previously they would just ignore the InterruptedException and stick around, gumming things up.
  • The interface-0-send-detect code no longer prints an error if the destination address is (invalidIP), on the assumption that the UDP socket was previously connected using SetUDPSocketTarget() in that case.
  • ReceiveDataUDP() now returns correct source-address/port information even when receiving IPv4 UDP packets while compiled with the MUSCLE_USE_IPV6 flag defined.

New in MUSCLE 5.31 (Jun 8, 2010)

  • Added LaunchIndepentChildProcess() static methods to the ChildProcessDataIO class, for quick fire-and-forget style launching of child processes.
  • Added an optional maxWaitTimeMicros argument to the ChildProcessDataIO::System() methods.
  • Added a QDataIODevice adaptor class to the qtsupport folder.
  • Made the MUSCLE GetCurrentThreadID() function publicly available (declared in system/SetupSystem.h).
  • Added a MUSCLE_ENABLE_DEADLOCK_FINDER flag.
  • The deadlock-finder no longer requires manual insertion of PLOCK and PUNLOCK macros everywhere; instead, that functionality is conditionally compiled into the Mutex class itself.
  • Added code to deadlockfinder.cpp to detect inconsistent sequences and print error messages about them, instead of just printing out all sequences and leaving it up to the user to detect any problems.
  • The deadlock-finder generation code now stores up its output in RAM until the process is exiting, and dumps it to stdout at that time. That way race conditions in accessing stdout are avoided, so the output won't be garbled.
  • LockLog() and UnlockLog() now lock/unlock a separate lock that is dedicated to the log callbacks only, instead of calling through to the global muscle lock.
  • InflateBuffer() and DeflateBuffer() now use their own Mutex also, for reasons similar to those listed above.
  • The Windows implementation of ChildProcessDataIO now marks its master/slave notify sockets as non-inheritable, so that subsequent child process won't hold them open unexpectedly.

New in MUSCLE 5.30 (May 8, 2010)

  • Added proper copy/assignment/equality operators to the StringMatcher class, and added a HashCode() method to it so that it can be a key in a Hashtable.
  • Added OP_CONTAINS_BITS and OP_DOESNT_CONTAIN_BITS operators to the NumericDataQueryFilter family of classes, so that you can do some bit-chord logic in a QueryFilter.
  • Added an Area() method to the Rect class.
  • Added optional checksum calculation and printing to hexterm.
  • Added a GetDefaultObject() method to the ObjectPool class that gives read-only access to the ObjectPool's persistent default-constructed object.
  • Added a GetEmptyByteBuffer() function to ByteBuffer.{cpp,h}
  • GetEmptyMessageRef() now returns a ConstMessageRef instead of a MessageRef, to ensure that the returned Message is not (easily) modified.
  • GetEmptyByteBufferRef() now returns a ConstByteBufferRef instead of a MessageRef, to ensure that the returned ByteBuffer is not (easily) modified.
  • Simplified the ObjectPool class to make it less error-prone and easier to use. The function callbacks are gone; instead, recycled objects are reset to their default state simply by using their assignment operator to set them equal to a default-constructed object.
  • IsRegexToken() no longer considers ':' to be a regex token. This change is because ':' is often used in otherwise non-regex strings, and is never the only regex character in a regex string.
  • Fixed some compiler warnings under MSVC 2008
  • Fixed a bug that would cause subscriptions not to be properly unsubscribed in some cases.

New in MUSCLE 5.23 (Apr 23, 2010)

  • The Parse*() functions in MiscUtilityFunctions.{cpp,h} now take an optional (caseSensitive) boolean argument. If left false (the default), parsing will be case sensitive, as it was in previous versions. If set to true, then arguments will be left in their original case and not forced to lower case.
  • Added information to the leaked-ObjectPool-Ref assertion failure error message, so that now the type and the address of the leaked reference(s) are printed out as part of the assertion failure.
  • Rewrote the ObjectNode class to use uint16 indices instead of pointers, to reduce memory usage (especially on 64-bit systems)
  • Added a Clear() convenience method to the Socket class.
  • Added Append() and Prepend() methods to the String class that take a char as an argument.
  • Changed the (recurse) argument in Message::PrintToStream(), Message::ToString(), and Message::AddToString() to a (maxRecurseLevel) uint32 argument instead, so that user-specified maximum recursion depths can be supported.
  • Re-organized the GlobalSocketCallbacks so that they all happen immediately after the socket is created.
  • Changed the "Couldn't disable V6-only mode" message to MUSCLE_LOG_DEBUG.
  • Made the Message(uint32) constructor explicit.
  • Tweaked the code so that hexterm once again compiles under Windows.
  • Tweaked NetworkUtilityFunction.cpp to build again even when MUSCLE_ENABLE_MULTICAST_API is not defined.
  • MUSCLE sockets now have IPV6_V6ONLY explicitly disabled when they are created, so that IPv4-mapped sockets will work even under operating systems that disable them by default (read: Windows 7)
  • The MCRASH macro no longer calls FatalAppExit() under windows; instead it just writes to a NULL pointer. That way if there is a crash handler installer, it will run.

New in MUSCLE 5.22 (Mar 4, 2010)

  • Added SetSocketKeepAliveBehavior() and GetSocketKeepAliveBehavior() functions to NetworkUtilityFunctions.{cpp,h}. Note that these functions are only available if MUSCLE_ENABLE_KEEPALIVE_API is defined.
  • Added SetGlobalSocketCallback() and GetGlobalSocketCallback() to NetworkUtilityFunctions.{cpp,h}, to allow all TCP sockets in the process to be set up in a similar way, if desired.
  • Added a portablereflectclient.vcproj file to the tests folder, so that portablereflectclient can be compiled under Microsoft Visual Studio.
  • The AtomicCounter class now uses the OSAtomicCounter.h atomic counter API when compiled under MacOS/X.
  • Added an optional (maxReplaceCount) arg to the String::Replace() methods.
  • Added a ServerComponent::IsFullyAttachedToServer() method, which returns true iff AttachedToServer() has already returned success, and AboutToDetachFromServer() hasn't been called yet.
  • Removed MUSCLE_CUSTOM_ATOMIC_TYPE support from the AtomicCounter class, since it wasn't useful and was cluttering up the code.
  • Rewrote the CalculateChecksum() and CalculateChecksumFor*() methods to call through to CalculateHashCode(), since the existing checksum algorithms were not very good at avoiding checksum collisions.
  • Updated win32client.vcproj and win32client.cpp to build properly again.
  • Fixed a couple of typos in AsyncDataIO.cpp.
  • GetFileLogName() is no longer included in the MUSCLE_INLINE_LOGGING headers in SysLog.h, since its inclusion caused chicken-and-egg problems.
  • Added inline versions of PrintStackTrace(), GetStackTrace(), GetLogLevelName(), and GetLogLevelKeyword().
  • Made all of the inline log functions into static inlines.

New in MUSCLE 5.21 (Jan 22, 2010)

  • Added UnparseFile() functions to MiscUtilityFunctions.{cpp,h}. These convert a ParseFile()-style Message back into a text file.
  • Added printsourcelocations.cpp to the tests folder. This program will scan a source code directory tree and print out the 4-letter source location codes corresponding to all calls to LogTime(), along with their human-readable location and the line of source code.
  • The source code location alphabet had the numeral '5' in it, which was not supposed to be there (it looks too much like 'S'). Removed it.
  • Fixed a bug where UnparseArg("arg= val") wouldn't parse correctly.
  • Fixed a potential race condition in ObjectPool::Drain().
  • Some dependencies were missing from the VC++ project files; added them.
  • Converted RefCount::CheckedGetItemPointer() from a method into a stand-alone inline function, because calling methods on a NULL pointer is specified as causing undefined behavior in C++, and therefore having CheckedGetItemPointer() as a method is unsafe.
  • Removed unnecessary files from the vc++ folder, updated vc++/README.txt

New in MUSCLE 5.20 (Dec 30, 2009)

  • UnparseArgs(const Queue &) now takes optional startIdx and afterEndIdx arguments.
  • Rewrote/simplified the HashtableIterator class: Removed all of the HasMore*(), GetNext*(), and PeekNext*() methods. The only methods remaining are GetKey(), GetValue(), HasData(), operator++(), and operator--().
  • Rewrote/simplified the MessageFieldNameIterator class: Removed the HasMoreFieldNames(), GetNextFieldName() and PeekNextFieldName() methods. The only methods remaining are HasData(), GetFieldName(), operator++, and operator--.
  • The String, Point and Rect classes no longer derive from Flattenable, and no longer have any virtual methods.
  • Removed the (initialSize) constructor argument from the Queue and PathMatcherQueue classes, since it was rarely used and added 4 bytes to the size of the Queue class.
  • debugcrashes is also now enabled under OS/X.
  • Rewrote the POSIX implementation of ChildProcessDataIO so that the marshalling of the child process's arguments array is done in the parent process rather than between fork() and execve(); that avoids potential problems with doing dynamic memory allocation during that awkward phase of the child's development.
  • Added a work-around in SendDataUDP() for a misfeature of MacOS/X (and possibly other IP stacks) where sendto() will send on the default interface even when the destination address clearly specifies another interface.
  • Replaced calls to gmtime() with gmtime_r(), for thread safety.

New in MUSCLE 5.11 (Nov 24, 2009)

  • Added GetHumanReadableTimeIntervalString() to SysLog.h.
  • Added GetEmptyByteBufferRef() to ByteBuffer.{cpp,h}.
  • Added a DataNode::GetChild() method that returns the result as a return value rather than as a by-reference parameter.
  • ParseHumanReadableTimeIntervalString() can now correctly parse multiple-clause time interval strings of the type generated by GetHumanReadableTimeIntervalString().
  • Added a GetPulseParent() method to the PulseNode class.
  • Removed the MUSCLE_ROUTING_FLAG_REFLECT_TO_SELF bit from the DEFAULT_MUSCLE_ROUTING_FLAGS_BIT_CHORD constant, since including this bit made the sessions' default routing behavior different from what it was (and is) documented to be.
  • BatchOperator now calls BatchEnds() from within the batch context instead of after the batch context has ended, for consistency with the semantics of BatchBegins().
  • Rewrote the Windows implementation of the Mutex class to use critical sections rather than locking a Windows Mutex directly, for better performance.
  • Renamed the Python files in the python folder from e.g. CamelCase.py to e.g. lower_underbar_case.py, per the Python Style Guide.
  • Made CalculateHashCode() and CalculateHashCode64() non-inline functions, since they are rather large to be inlined.
  • Rewrote the Xenomai implementation of GetRunTime64() to call rt_timer_tsc() instead of rt_timer_read(), so that the value returned is nanoseconds-since-boot, not nanoseconds-since-1970.
  • The "realtime" command line argument support now memsets() the sched_param struct to zero before filling it out, just in case it has other members besides sched_priority.
  • Fixed a bug in the Hashtable class where copying one Hashtable to another could cause multiple identical entries to appear in the target table's iteration list.

New in MUSCLE 5.10 (Oct 14, 2009)

  • Added a HashCode() method to the Tuple, Point, and Rect classes, so that they can now be used as keys in a Hashtable.
  • Added a Hashtable::Intersect() convenience method.
  • Added SetRoutingFlag() and IsRoutingFlagSet() methods to the DumbReflectSession class. These flags allow subclasses of DumbReflectSession to change default/unrecognized routing behavior to be more appropriate for their needs, if necessary.
  • Added two new parameters that can be set via PR_COMMAND_SETPARAMETERS and got via PR_COMMAND_GETPARAMETERS. They are PR_NAME_ROUTE_GATEWAY_TO_NEIGHBORS and PR_NAME_ROUTE_NEIGHBORS_TO_GATEWAY and they control the similarly named bits in the DumbReflectSession class.
  • Added a (reconnectViaTCP) argument to the AbstractReflectSession:: SetAsyncConnectDestination() method, so you can specify whether Reconnect() should connect to the supplied address via a standard TCP connection, or not.
  • The file log name (as set by the "logfile" command line argument or SetFileLogName()) is now interpreted by HumanReadableTimeValues::ExpandTokens(), so it can use any of the standard tokens and they will be expanded to their values at the time the log file is created.
  • File logging now supports maximum log file sizes (via the "maxlogfilesize=n" keyword and via the new SetMaxLogFileSize() and GetMaxLogFileSize() functions). When a log file becomes larger than the specified size, it will be closed and a new log file opened.
  • Log files closed because they are too large can be optionally gzip-compressed (if the "compresslogfiles" keyword is specified, or via the new SetFileLogCompressionEnabled() function)
  • Added an optional "maxnumlogfiles" argument (and associated SetMaxNumLogFiles() and GetMaxNumLogFiles() functions) that allow you to specify that old log files should start to be deleted after a certain number of log files have been created.
  • Added an optional "oldlogfilespattern" argument (and associated SetOldLogFilesPattern() function) that lets you specify the pattern of file-paths that can be safely assumed to be old log files from previous instances of the current application, and deleted if necessary.
  • Added a SetFile() method to the FileDataIO class.
  • Added AppendBytes() methods to the ByteBuffer class.
  • Added InflateByteBuffer() and DeflateByteBuffer() functions to ZLibUtilityFunctions.{cpp,h}.
  • Added raw-pointer versions of the Inflate(), Deflate(), and GetInflatedSize() methods of the ZLibCodec class.
  • Set EXTRACT_ALL to yes in the muscle.dox file, so that the non-member functions will show up in the DOyxgen documentation.
  • Added Doxygen groups around the non-class APIs, so that they show up as Modules in the Doxygen HTML.
  • Added a brief Doxygen mainpage introduction blurb.
  • Changed the MUSCLE_VERSION macro in support/MuscleSupport.h from hexadecimal to decimal, so it can be more readable.
  • FileDataIO ctor's argument now defaults to NULL.
  • Log() and LogTime() no longer inhibit re-entrant calls during log callbacks. This allows the callbacks to do logging themselves, although they do need to be careful to avoid infinite recursions.
  • GetNumAvailableBytes(), GetMaxNumBytes(), and GetNumUsedBytes() now return uint64's instead of uint32's, so that they can deal with more than 4 gigabytes of RAM allocation.
  • DumbReflectSession::SetReflectToSelf() and GetReflectToSelf() are now deprecated inline synonyms for SetRoutingFlag(MUSCLE_ROUTING_FLAG_REFLECT_TO_SELF) and GetRoutingFlag(MUSCLE_ROUTING_FLAG_REFLECT_TO_SELF), respectively.
  • ParseArgs() no longer strips leading dashes off of the arguments it parses, because doing that made it impossible to pass negative numbers as command line arguments.
  • Added a PrintStackTrace() comment to SysLog.cpp for easy copy-and-paste to third party code when necessary.
  • Moved the HumanReadableTimeValues class and its related functions out of MiscUtilityFunctions.{cpp,h} and into SysLog.{cpp,h}, so that programs that use the system log but not the other functions in MiscUtilityFunctions.cpp do not need to link in MiscUtilityFunctions.cpp.
  • Moved Atoll() and Atoull() from MiscUtilityFunctions.{cpp,h} to SetupSystem.cpp and MuscleSupport.h, for the same reasons.
  • Fixed some printf() formatting warnings that occurred when the C code (MiniMessage, etc) was compiled on a 64-bit OS.
  • Changed a constant in SharedUsageLimitProxyMemoryAllocator from MUSCLE_NO_LIMIT to ((size_t)-1) so that it would work properly under 64-bit OS's.
  • NetworkInterfaceInfo::ToString() was broken. Fixed.

New in MUSCLE 5.00 (Sep 17, 2009)

  • Added a MUSCLE_VERSION define that is the numeric counterpart to the MUSCLE_VERSION_STRING define. This makes it easier to write code that will build against multiple MUSCLE versions, if necessary.
  • Split DataIO::GetSelectSocket() into two methods, GetReadSelectSocket() and GetWriteSelectSocket(). This way a DataIO can use two different file handles for event-catching if it wants to.
  • Split AbstractReflectSession::GetSessionSelectSocket() into GetSessionReadSelectSocket() and GetSessionWriteSelectSocket().
  • Reimplemented the ARRAYITEMS macro in C++ land to be a templated function instead. This has the advantage of making it a compile-time error if you try to call ARRAYITEMS() with a pointer argument.
  • muscleCompare() now depends only on the less-than operator. Before it depended on less-than and greater-than working as expected.
  • Removed the DECLARE_HASHTABLE_KEY_CLASS* macros, since they are no longer needed. Appropriate HashFunctors are now selected automatically through SFINAE magic; all the user has to do is add a "uint32 HashCode() const" method into his key class and it will be used.
  • HashFunctor classes now also have a AreKeysEqual() method for determining whether two keys are equivalent or not in a type-appropriate manner.
  • Added support for a MUSCLE_COLLECT_HASHTABLE_COLLISION_STATISTICS #ifdef which can be used to test the efficacy of different hash functions.
  • Added CalculateHashCode() and CalculateHashCode64() functions to MuscleSupport.h. These functions return hash codes for any array of bytes using Austin Appleby's MurmurHash2_Aligned algorithms.
  • The Hashtable class no longer chooses its array sizes based on prime numbers; instead it now relies on a better hash function (MurmurHash2.0) that will hash values well no matter what the array size is.
  • Optimized the String class's reallocation strategy to conserve memory better when dealing with very long strings.
  • Added a GetNumAllocatedBytes() method to the String class.
  • Added IsValid() and IsNull() convenience methods to the ConstRef class.
  • Added a version of DataNode::GetNodePath() that returns a String.
  • Added ToCaseInsensitive(const String &) to regex/StringMatcher.h
  • Added a PutOrRemove() method to the Hashtable class that takes a pointer to the value (NULL pointer means remove).
  • Added a GetAncestorNode() convenience method to the DataNode class.
  • Added ++ and -- operators to the String class. (they add a space and remove the last character in the string, respectively)
  • ParseHumanReadableTimeIntervalString() now recognized special strings "forever", "never", and "infinite" and will return MUSCLE_TIME_NEVER in response to any of those keywords.
  • ParseFile() can now accept its file data in the form of a String as well as a (FILE *).
  • Added BroadcastToAllSessionsOfType() templated methods to the AbstractReflectSession and ReflectSessionFactory classes.
  • Added GetWithDefault() methods to the Queue class.
  • Added a GetDataIO() convenience method to the AbstractReflectSession class.
  • Added a GNII_INCLUDE_NONLOOPBACK_INTERFACES, GNII_INCLUDE_ENABLED_INTERFACES, and GNII_INCLUDE_DISABLED_INTERFACES flags GetNetworkInterfaceInfos() function's flag argument options.
  • Merged in Monni's patch to make the B_SWAP_*() macros call through to MSVC's _byteswap_*() functions on versions of MSVC that support that.
  • Added a Contains(const ItemType &) convenience method to the Queue class.
  • AbstractMessageIOGateway now derives from AbstractGatewayMessageReceiver, so that you can link the input of one gateway directly to the output of another if you want to.
  • Added a SetFilterForEntry() method to the PathMatcher class so that existing PathMatcherEntry objects can have their filters updated without throwing the PathMatcher class's filter-count out of whack.
  • Added ToString() methods to the PathMatcherEntry and StringMatcherQueue classes, to better facilitate debugging.
  • Removed CStringHashFunc() and CStringHashFunc64() functions; any code that was previously using those should call CalculateHashCode(s,strlen(s)) instead.
  • Split the Hashtable class auto-sort functionality out into subclasses. The Hashtable class no longer supports auto-sort; instead you now instantiate an OrderedKeysHashtable or an OrderedValuesHashtable if you want a table that keeps its data sorted.
  • All Hashtable sorting is now done via CompareFunctors instead of via function pointers.
  • Rewrote the Queue::Sort() method to used a templatized CompareFunctor object instead of a function pointer. This allows the compiler to inline the comparisons for better performance, and also frees the programmer from having to manually specify a comparison function in most cases.
  • Remove the Compare*() callback functions from MuscleSupport.h because they are no longer needed (use functors instead)
  • Made PulseNode::InvalidatePulseTime() public instead of protected.
  • Made the object-capturing constructors in the RefCount and ConstRefCount classes explicit, so that object-capture can't happen without the programmer's explicit knowledge.
  • ExecuteSynchronousMessageRPCCall() now returned an empty Message if it connects successfully but receives no reply. That way the caller can differentiate that case from the could-not-connect case.
  • Removed UNLESS() macro, since it was never used and was bad style.
  • FindFirstSessionOfType() and FindSessionsOfType() template methods now take as their template argument, not
  • Removed some characters from the source-location-code alphabet to reduce the risk of inadvertent swearing in the lock file.
  • Rewrote the Windows implemetation of StdinDataIO (again) so that closing a StdinDataIO object no longer tries to shut down the Stdin I/O thread. That appears impossible to do reliably under the awesome Windows API, so now the Stdin I/O thread is a singleton that always runs (safely minding its own business) until stdin closes.
  • Fixed a typo in MessageTransceiverThread.py
  • ExecuteSynchronousMessageRPCCall() now includes the TCP-connect time in its calculations regarding the timeout period.
  • ParseHumanReadableTimeInterval() now defaults to seconds when no units are specified (previously it would return zero in that case).
  • String::operator-(const char) had a bug where it would read one byte too many as part of its memmove() call. Fixed.
  • Atoll() and Atoull() weren't handling invalid strings (with preceding non-digit characters) properly. Fixed.
  • Added a _M_AMD64 case ot the LITTLE_ENDIAN byte ordering detection, per Mika Lindqvist's suggestion.
  • GetNetworkInterfaceInfos() no longer returns results for interfaces that are not currently up/enabled.
  • SharedFilterSessionFactory::CreateSession() now assumes that any connection coming in over the Loopback device is a local connection, even if the source IP address isn't recognized as a local address (a situation that can happen on a Mac when an interface has been disabled)
  • Fixed a bug in AbstractMessageIOGateway::ExecuteSynchronousMessaging() that would cause it to sometimes return B_ERROR even when it had, in fact, successfully completed.
  • In MUSCLE_USE_IPV6 mode, IsIPv4Address() no longer returns true for IPv4 addresses ::1 and ::, as these are commonly used IPv6 addresses.
  • Fixed two bugs that could cause StorageReflectSession do do subscription updating incorrectly when using QueryFilters in the subscriptions.

New in MUSCLE 4.63 (Jul 20, 2009)

  • When compiled with MUSCLE_USE_IPV6 enabled, MUSCLE now does automatic transparent remapping of IPv4-compatible IPv6 addresses into IPv4-mapped IPv6 addresses. This allows MUSCLE servers to be 100% compatible with both IPv4 and IPv6 clients (on platforms that support dual stacks, of course) without any additional effort on the programemr's part.
  • Added SetAutomaticIPv4AddressMappingEnabled() and GetAutomaticIPv4AddressMappingEnabled() calls to NetworkUtilityFunctions.{cpp,h}.
  • Added CAdd*() and CPrepend*() convenience methods to the Message API, to the common "add value to Message unless it's the default value" idiom quicker and easier to express.
  • Added Contains() convenience methods to the String class.
  • Added an optional (optRetTotal) argument to SharedUsageLimitProxyMemoryAllocator::GetCurrentMemoryUsage().
  • Added a ParseHumanReadableTimeIntervalString() convenience function to MiscUtilityFunctions.cpp.
  • Added an static Exists() method to the Directory class.
  • Added a PutOrRemove() convenience method to the Hashtable class.
  • Added an IsValidIP() function to NetworkUtilityFunctions.{cpp,h}.
  • GetNextEventFromInternalThread() now has an optLocation parameter that can be used to find out the IP address and port that a session connected to (or what accepted from).
  • The SessionConnected() signals of the QMessageTransceiverThread and QMessageTransceiverHandler classes now include an IPAddressAndPort object indicating what the session connected to.
  • The SessionAccepted() signal of the QMessageTransceiverThread class now includes an IPAddressAndPort object indicating where the session was accepted from.
  • Added SetAsyncConnectDestination() and GetAsyncConnectDestination() methods to the AbstractReflectSession class.
  • Added ToString() methods to the SegmentedStringMatcher and StringMatcher classes.
  • SegmentedStringMatcher no longer bothers to allocate a StringMatcher object for clauses that are represented by "*".
  • Renamed DataNode::CountChildren() to DataNode::GetNumChildren().
  • Renamed DataNode::SetMaxKnownChildID() to DataNode::SetMaxKnownChildIDHint().
  • Renamed Message::CountNames() to Message::GetNumNames().
  • Rewrote the static internal function AdjustValue() in SharedUsageLimitAllocator.cpp to give more informative error output.
  • Removed Message::GetConstPointer() since you can use GetPointer() to do the same thing (by assigning a const pointer to the result).
  • Documented some methods that were previously not documented.
  • Fixed a bug where SharedUsageLimitAllocator::ResetDaemonCounter() could push the cumulative memory counter into negative territory.
  • Inet_NtoA was allowing the IPv6-specific "@3" interface-index suffix into IPv4-style address strings. Fixed.
  • SetupSystem.cpp's Muscle_GetCurrentThread() wasn't working properly on 64-bit OS's. Fixed.

New in MUSCLE 4.62 (Jun 18, 2009)

  • Added a ThreadLocalStorage class to the muscle/system sub-folder. This class makes it easy for each thread to access its own local copy of a global object, without any need for Mutex locking/unlocking overhead.
  • Added a Thread::GetCurrentThread() static method, so that any Thread can access its Thread object conveniently.
  • Added additional fields to the PR_RESULT_PARAMETERS Message: PR_NAME_SERVER_CURRENTTIMEUTC (server's GetCurrentTime(UTC)) PR_NAME_SERVER_CURRENTTIMELOCAL (server's GetCurrentTime(LOCAL)) PR_NAME_SERVER_RUNTIME (server's GetRunTime64())
  • Added a AddApplicationSpecificParametersToParametersResultMessage() method to the StorageReflectSession class. It allows a subclass to add fields to the PR_RESULT_PARAMETERS Message before it goes back to the client.
  • Added an IsIPv4Address() function to NetworkUtilityFunctions.{cpp,h}
  • Added GetSendDestinations() methods to the UDPSocketDataIO object. With these methods you can have the UDPSocketDataIO object send the same UDP packet to multiple destinations whenever Write() is called.
  • Added a GetDefaultItem() method to the Queue class.
  • Added GetDefaultKey() and GetDefaultValue() methods to the Hashtable class.
  • If TARGET_PLATFORM_XENOMAI is defined, GetRunTime64() now uses Xenomai's rt_timer_read() function to determine its result.
  • GetNetworkInterfaceInfos() and GetNetworkInterfaceAddresses() now accept a bit-chord of GNII_INCLUDE_* bits as their second argument, rather than a simple boolean. This allows the caller to express in a bit more detail which sorts of interfaces he is interested in.
  • Added a convenience constructor to the AndOrQueryFilter class.
  • Added testthread.cpp back in to the test/Makefile.
  • Modified testthread.cpp to test the ThreadLocalStorage class also.
  • Reorganized the ObjectPool.h class implementation.
  • Simplified the Qt implementation of the Thread class.
  • system/Mutex.h now #includes support/MuscleSupport.h, so that the Win32 build environment is detected properly even when system/Mutex.h is the first #include.

New in MUSCLE 4.61 (May 23, 2009)

  • Added GetTotalNumSignalsReceived() and
  • GetNumSignalsReceivedOfType() methods to the
  • SignalMultiplexer class.
  • Added an IsCurrentThreadMainThread() function to
  • SetupSystem.{cpp,h}.
  • Added support for a "catchsignals" keyword to
  • HandleStandardDaemonArgs(). This keyword, if
  • specified, will cause the main thread's
  • ReflectSession() (if any) to add a signal handler
  • session to itself.
  • Added support for a MUSCLE_AVOID_SIGNAL_HANDLING compiler
  • flag that can be defined by applications that don't
  • want to compile in signal handling support.
  • Added a SignalChildProcess() method to the
  • ChildProcessDataIO class.
  • ChildProcessDataIO::WaitForChildProcessToExit()
  • now takes an optional timeout value, and returns
  • true if the child exited or false if it timed out.
  • In the ChildProcessDataIO class, I replaced
  • SetKillChildOnClose() and SetWaitForChildOnClose() with
  • a single SetChildProcessShutdownBehavior() method which
  • provides for more flexibility, making it possible to
  • do a "soft shutdown with a hard kill after a timeout".
  • Removed the "catchsignals" support from muscledMain()'s
  • setup code, since that support is now part of
  • HandleStandardDaemonArgs() instead.

New in MUSCLE 4.60 (May 16, 2009)

  • The Message class now derives from Cloneable.
  • The Message::FindInt*() methods class now accept both signed and unsigned value arguments, so that dangerous C-style casting is no longer necessary when retrieving unsigned integer values.
  • Added a set of Message::Get*() methods that are similar to Message::Find*() except that they return the found value instead of a status code. (if the requested value is not found, they return a user-provided default value instead)
  • The Message::Find*() methods now take their value parameters by reference instead of by pointer. (e.g. msg.FindInt8("foo", x) instead of msg.FindInt8("foo", &x). The old by-pointer style is still supported, but is deprecated.
  • Added a Queue::LastIndexOf() method that does a reverse search in a Queue, optionally within a specified index range.
  • Added a Flattenable::UnflattenFromByteBuffer() method that takes a ConstByteBufferRef argument, per Mika's request.
  • Added SetLowBits(), SetHighBits() to the IPv6 ip_address class.
  • When MUSCLE_USE_IPV6 is defined, the ip_address class now includes an interface-address field. Inet_AtoN() and Inet_NtoA() now append/expect this field at the end of the string if the interface is non-zero (e.g. "fe80::1@3")
  • Upgraded the multicast API to properly support IPv6 multicast. In particular, when MUSCLE_USE_IPV6 is defined, AddSocketToMulticastGroup() and RemoveSocketFromMulticastGroup() no longer take an interface IP address (instead they use the interface index included in the groupAddress argument). Also SetSocketMulticastSendInterfaceAddress() and GetSocketMulticastSendInterfaceAddress() are replaced by SetSocketMulticastSendInterfaceIndex() and GetSocketMulticastSendInterfaceIndex(). This is necessary because IPv6 doesn't identify interfaces by IP address, rather it identifies them with integers.
  • Added a broadcastIP_IPv4 constant to NetworkUtilityFunctions.h to allow IPv4 braodcasts even in IPv6 mode.
  • Added a localhostIP_IPv4 constant to NetworkUtilityFunctions.h to allow references to the IPv4 localhost device in IPv6 mode.
  • Added a GetHashCodeForIPAddress() function to NetworkUtilityFunctions.h, to avoid #ifdefs in application code.
  • Added a IsMulticastIPAddress(const ip_address &) function to NetworkUtilityFunctions.{cpp,h} that returns true iff the specified address is a multicast addess.
  • Added a IsStandardLoopbackDeviceAddress(const ip_address &) function to NetworkUtilityFunctions.h, since under IPv6 localhostIP has several names and thus doing a literal numeric comparison to (localhostIP) can be error-prone.
  • Added a GetConnectString(const String &, uint16) convenience function to MiscUtilityFunctions.{cpp,h}, to generate strings like "localhost:9999" or "[ff05::1]:9999" correctly.
  • Added an ExecuteSynchronousMessageRPCCall() function to MessageIOGateway.{cpp,h}. This function connects to a server via TCP, sends a Message, received a Message, and returns the received Message, so that you can "call" a server, RPC-style, as if it was a local function.
  • Added a GetLocalHostName() function to NetworkUtilifyFunctions.{cpp,h}.
  • Added a HashCode64() method to the String class, and a CStringHashFunc64() function that it calls.
  • Added a ToString() method to the NetworkInterfaceInfo class.
  • Improved the parsing of IPAddressAndPort and ParseConnectArg() so that they now properly handle IPv6 hostname-and-port strings that don't contain brackets, when possible.
  • Added a version of ParseConnectArg() that takes a direct String (instead of a Message and field name)
  • Rewrite the Win32 implementation of GetNetworkInterfaceInfos() to use GetAdaptersAddresses() instead of GetIpAddrTable(), so that it can detect IPv6 addresses as well as IPv4.
  • Added an optional (preferIPv4Style) argument to Inet_NtoA() so that if you prefer, IPv4 addresses can be returned in the classic style ("192.168.1.1") instead of new-style ("::192.168.1.1")
  • Added support for the MUSCLE_INCLUDE_SOURCE_LOCATION_IN_LOGTIME compiler flag, which if specified will cause every call to LogTime() to include location info (source file name and line number) in the log information. This can be useful for tracking down exactly where a particular log message came from.
  • When MUSCLE_INCLUDE_LOCATION_IN_LOGTIME is defined, the standard log-line preamble now includes the string returned by GetStandardLogLinePreamble().
  • Added GenerateSourceCodeLocationKey(), SourceCodeLocationKeyToString(), and SourceCodeLocationKeyFromString() functions to Syslog.{cpp,h}
  • Added a utility called "findsourcelocations" to the tests folder. This utility will find possible locations for source code keys in the specified directory hierarchy.
  • Added a HashCode() method to the NetworkInterfaceInfo class.
  • The Directory class is now a subclass of RefCountable.
  • Added a GetPath() method to the Directory class.
  • Added FileExists(), RenameFile(), CopyFile(), and DeleteFile() utility functions to util/MiscUtilityFunctions.{cpp,h}.
  • Added an MEXIT(ret,msg) macro to MuscleSupport.h. It's the same as MCRASH, but it doesn't crash, it merely ends the process (by calling ExitWithoutCleanup(ret)).
  • Added a Reset() method to the StringMatcher class.
  • Added a WasConnected() method to AbstractReflectSession, so that subclasses can find out if the session ever was connected to its remote peer.
  • ExpandLocalhostAddress() now caches its first result from GetNetworkInterfaceInfos() so that it no longer has to call GetNetworkInterfaceInfos() every time it is called.
  • Added a GetServerSessionID() method to the ReflectServer class, and a PR_NAME_SERVER_SESSION_ID field to the standard parameters set, so that clients can access a 64-bit value that is unique to the current server instance.
  • Added a SignalMultiplexer class that deals with POSIX signals or Windows Console signalling in a unified manner.
  • Added a QSignalHandler class that can emit a Qt signal when a POSIX/Windows signal is received.
  • Added a SignalHandlerSession class that you can add to your ReflectServer if you want signals to result in a graceful shutdown (or other custom behavior)
  • The Python MessageTransceiverThread class constructor now takes a boolean argument which indicates whether or not it should use IPv6 networking.
  • Added a GetHumanReadableProgramNameFromArgv0(const char *) convenience function to MiscUtilityFunctions.{cpp,h}.
  • Added a Win32AllocateStdioConsole() function that allocates a console window for stdio to use under Windows.
  • Added CleanupDNSLabel() and CleanupDNSPath() functions to MiscUtilityFunctions.{cpp,h}. These are handy for removing errors from user-entered DNS hostnames (e.g. "www.foo.com").
  • Rewrote String::LastIndexOf(char) and the String -= operators to be more efficient.
  • The arguments to the Log() method in the LogCallback API are now consolidated into a single LogCallbackArgs object, for efficiency and cleaner code.
  • The GetStandardLogLinePreamble() function now takes a single LogCallbackArgs argument instead of separate args also.
  • Removed support for the MUSCLE_AVOID_NAMESPACES, BEGIN_NAMESPACE, END_NAMESPACE, and USING_NAMESPACE macros, since they aren't necessary and use of macros to control namespaces can confuse Qt's moc utility.
  • Rewrote portablereflectclient to use StdinDataIO instead of accessing stdin directly. This allows it to work correctly under Windows, and simplifies the code.
  • Queue::IndexOf() was defined as returning the last matching item, which was inconsistent. Replaced it with a new IndexOf() implementation that does a forward search, optionally within a specified index range.
  • Suppressed a warning in zip.c
  • Removed the explicit signal handling from the ReflectServer class (SetSignalHandlingEnabled() and WasSignalCaught() are gone now). This functionality is now handled by the SignalHandlerSession class instead.
  • The Win32 "console" keyword wasn't redirecting stdin. Fixed.
  • Fixed a syntax error in the EnsureRefIsPrivate() method.
  • Updated the VC++ project files so they build again.
  • ParseConnectArg() now handles the "[ipv6::addr]:port" syntax properly when MUSCLE_USE_IPV6 is defined.
  • Fixed a bug in the PulseChild class that would sometimes prevent the GetPulseTime() method of grandchild PulseChild nodes from getting called after InvalidatePulseTime() was called on them.
  • AbstractReflectClient::Reconnect() now sets the _wasConnected flag to false.
  • Fixed a bug in MessageTransceiverThread::AddNewWorkerConnectSession() that was causing disconnect notifications not to be sent for connect-sessions whose connections failed synchronously.
  • IntCompareFunc() was taking an int8 argument by mistake. Fixed.

New in MUSCLE 4.51 (Mar 24, 2009)

  • Added GetByteBufferFromPool() functions that accept a Flattenable object as an argument, for convenience.
  • Added a Message::GetPointerToNormalizedFieldData() method, which is useful if you need efficient direct (array-style) access to the contents of a data field in a Message object.
  • Added NumericAwareStringCompareFunc() functions to String.{cpp,h}. These routines are based on Martin Pool's number-aware string compare code, and compare strings in such a way that numbers in the strings are sorted properly.
  • Added a SegmentedStringMatcher class to the regex folder, for easy multi-level regex matching in e.g. file paths.
  • Added GetStringMatcherFromPool() convenience functions to regex/StringMatcher.{cpp,h}.
  • Added a ParseHexBytes() convenience function to MiscUtilityFunctions.{cpp,h}
  • Added a PrintToStream() method to the ByteBuffer class.
  • Added Bryan Varner's UDPClient class to the Java archive. This class facilitates sending small MUSCLE Messages over UDP in Java programs. Thanks Bryan!
  • Added Bryan Varner's DatagramPacketTransceiver class to the Java archive. This class allow Java applications to send large MUSCLE Messages over UDP in Java programs, by breaking them up into multiple chunks that are sent in successive UDP packets and then re-assembled by the receiver. This class is compatible with MUSCLE's C++ PacketTunnelIOGateway class. Thanks again, Bryan!
  • Added LaunchChildProcess() and System() methods to the ChildProcessDataIO class that takes a Queue as an argument, for convenience.
  • Added implementations of ParseArg(), ParseArgs(), ParseFile(), and UnparseArgs() that take a Queue to hold the parsed arguments rather than a Message. This is useful in cases where argument ordering must be preserved 100%.
  • Added a Directory::MakeDirectoryForFile() convenience method. It creates a directory for the specified file to be created in.
  • RemoveEscapeChars() and EscapeRegexTokens() now take a const String and return a String. This makes them easier to use in nested function calls.
  • Repackaged the com.lcs.* Java hierarchy as com.meyer.*, to reflect my company's name change.
  • Removed the Visual Cafe project from the archive, as it is obsolete and I am no longer using Visual Cafe and thus cannot easily update it.
  • Fixed template problems with gcc4 in BThread.h and AThread.h
  • The Windows implementation of StdinDataIO now freopens stdin as "nul", so that no other code will try to access stdin. This was done to keep third party libraries (read: Python 2.6) from trying to muck with stdin while the StdinDataIO thread was using and getting hung up.

New in MUSCLE 4.50 (Jan 29, 2009)

  • NullDataIO's constructor now takes an optional ConstSocketRef argument, to let you specify the value that its GetSelectSocket() method should return.
  • Added a GetMessageFromPool(const ByteBuffer &) inline convenience function.
  • Added another AddNewSession() convenience method to the MessageTransceiverThread class.
  • In the Message class, MoveName(), CopyName(), and ShareName() all now take an optional target-field-name parameter, in case you want to have a different field name in the target Message.
  • Added an EnsureFieldIsPrivate(const String & fieldName) method to the Message class. This method is useful to avoid side effects when modifying possibly-shared Message fields' contents.
  • Added an "cleanup callbacks queue" to the CompleteSetupSystem class, so that you can specify actions that should be taken as part of the CompleteSetupSystem destructor's cleanup steps.
  • Added a static GetCurrentCompleteSetupSystem() method to the CompleteSetupSystem class, to make it easier for code to find the current CompleteSetupSystem object.
  • Added MUSCLE_CATCH_SIGNALS_BY_DEFAULT #ifdefs... if this is set, ReflectServer will enable Control-C detection (and graceful shutdowns) by default.
  • GetOSName() now accepts an optional string value to return in the case where it can't determine the local OS name.
  • Added a MUSCLE_UNIQUE_NAME macro to MuscleSupport.h which will evaluate to a unique identifier based on the line number that the macro is invoked on.
  • Added a DECLARE_ANONYMOUS_STACK_OBJECT macro to MuscleSupport.h to allow easy declaration of anonymous objects on the stack.
  • Added util/BatchOperator.h, which contains the BatchOperator and BatchOperatorGuard utility classes that help automate the amortization of setup/shutdown routines across a nested call tree, for more efficient batch processing.
  • Added a DECLARE_BATCHGUARD() macro for each declaration of batched areas of code.
  • Added a DECLARE_MUTEXGUARD(m) macro to support declaring an anonymous MutexGuard on the stack in a simple and foolproof way.
  • hexterm now automatically enables the UDP broadcast flag on its UDP socket when the specified UDP address is a broadcast address.
  • Added a Cloneable interface in util/Cloneable.h, and updated ConstRefCount::EnsureRefIsPrivate() to use it when appopriate.
  • Added a Clone() method to the ConstRefCount class, for easy copying of referenced items.
  • Redesigned hexterm to be Win32 compatible.
  • Added a hexterm.vcproj file to the tests folder, to compile hexterm under Win32/VC++.
  • Added a "child=" option to hexterm so it can spawn and communicate with a child process if you want it to.
  • Added a "ascii" keyword argument to hexterm so you can send and receive data in ASCII format rather than hex, if you prefer.
  • Added LogHexBytes() functions to MiscUtilityFunctions.h. These are the same as PrintHexBytes() except that they call through to Log() instead of directly to fprintf().
  • Added an optional (portRequired) argument to ParseConnectArg().
  • Added SetLogFileName()/GetLogFileName() to util/SysLog.{cpp,h}.
  • Added a standard "logfile" keyword so you can specify the name and/or location of a log file to write the log to.
  • Added a WaitForChildProcessToExit() method to the ChildProcessDataIO class.
  • Added ChildProcessDataIO::System() static convenience methods.
  • Added a Directory::DeleteDirectory() static convenience method.
  • Rolled in Mika Lindqvist's Haiku-compatibility patches.
  • Renamed the standard "log" and "display" keywords to "filelevel" and "displaylevel", respectively.
  • Removed the OutOfMemoryCallback and FunctionOutOfMemoryCallback classes and replaced them with more general-purpose GenericCallback and FunctionGenericCallback classes.
  • Tweaked a call to FD_ISSET() in system/Thread.cpp in order to avoid a compiler warning under g++ 4.3.1
  • Tweaked the _PLOCKimp and _PUNLOCKimp debug functions to compile properly in 64-bit environments.
  • Updated the Message.h doxygen documentation with some more descriptive parameter names.
  • hexterm no longer disables multicast-to-self when sending multicast UDP packets.
  • Removed DebugTimer.cpp; that code has moved to SetupSystem.cpp.
  • Updated all copyright notice headers to read 2000-2009 Meyer Sound.
  • DebugTimer now uses GetRunTime64() if MUSCLE_USE_LIBRT is defined.
  • Fixed some #ifdef problems involving the stat64() call in FilePathInfo.h. FilePathInfo.h should now compile under both 32-bit and 64-bit environments.
  • JeffK added a macosx.mak file to the muscle/zlib/zlib folder, to support creation of universal binaries that include zlib.
  • MuscleSupport.h now checks a much more exhaustive list of Intel-compatible processor-type macros before deciding that inline x86 assembly code is not an option. In particular, compiling with an __i686__ target now does the right thing.
  • Fixed a potential infinite recursion in Thread::WaitForNextMessageAux().
  • Tweaked the SharedMemory.h include directives to compile more reliably under Win32.
  • Updated the #ifdefs in MuscleSupport.h to define int64's and uint64's properly under 64-bit Ubuntu Linux.
  • Rewrote the Win32 implementation of StdinDataIO to be simpler and more reliable.
  • The Win32 implementation of the INT64_FORMAT_SPEC macros was incorrect. Fixed it to do the right thing.
  • Made ChildProcessDataIO::LaunchChildProcess() const-correct.
  • ChildProcessDataIO::LaunchChildProcess() now specifies the application name to launch, when possible, for better security. (See Microsoft's CreateProcess() man page for details)

New in MUSCLE 4.41 (Nov 18, 2008)

  • Added an implementation of PrintHexBytes() that takes a Queue as an argument.
  • Added GetArchiveMessageFromPool() functions to Message.{cpp,h}. These templated convenience functions let you convert any object (with a SaveToArchive() method) into a MessageRef with a single command.
  • Added FindArchiveMessage() and FindArchiveMessageWithDefault() template methods to the Message class, for convenient one-step restoring of archived objects.
  • Added AddArchiveMessage(), PrependArchiveMessage(), and ReplaceArchiveMessage() template methods to the Message class, for further convenience in archiving objects.
  • GetHumanReadableTimeValues() now writes into a HumanReadableTimeValues object instead of into a series of by-reference int parameters. The HumanReadableTimeValues object now also includes day-of-week and microsecond fields.
  • Added an ExpandTokens() method to the HumanReadableTimeValues class that makes it easy to generate time/date stamps of your preferred format using various printf()-style field specifiers.
  • ProxySessionFactory::IsReadyToAcceptSessions() wasn't passing the call onto the slave session like it was supposed to. Fixed.
  • The calls to open() inside SpawnDaemonProcess() now supply a mode argument to the open() call.
  • AcceptSocketsThread.cpp wasn't compiling due to a const/non-const issue. Fixed.
  • Fixed several bugs in the admin utility. Thanks to Monni for pointing them out and supplying a patch.

New in MUSCLE 4.40 (Oct 17, 2008)

  • The Ref class now subclasses from a ConstRef class, which is the same as Ref except that it only allows read-only access to the held RefCountable object.
  • Added a CastAwayConstFromRef() template function to RefCount.h, so you can easily convert a ConstRef to a Ref if you really need to.
  • Renamed the SocketRef class to ConstSocketRef, because it now derives from ConstRef instead of Ref.
  • Added a DECLARE_REFTYPES macro to RefCount.h, which you can use to declare the standard BlahRef and ConstBlahRef typedefs without having to specify the typedefs manually every time.
  • Added implementations of the Connect() and ConnectAsync() functions that take an IPAddressAndPort object as an argument.
  • Added *_FORMAT_SPEC_NOPERCENT macros, for times when I need to specify format specifications without the percent sign included.
  • Added an AsyncDataIO class that can be used to transparently forward I/O operations to a separate thread, to avoid blocking in your main thread. This can be useful for DataIO classes that don't support non-blocking I/O (e.g. FileDataIO)
  • Added a GetStackTrace() function to SysLog.{cpp,h} that returns the current stack trace as a String.
  • Added GetLightweightCopyOfMessage() convenience functions to Message.{cpp,h}.
  • Added convenience methods FindFirstSessionOfType() and FindSessionsOfType() to the ServerComponent class. These methods are templated to let you quickly find and collect one or more atatched session objects of the specified C++ class.
  • Renamed GenericRef to RefCountableRef, for consistency.
  • Renamed PolicyRef to AbstractSessionIOPolicyRef, for consistency.
  • Renamed Ref::SetFromGeneric() and Ref::GetGeneric() to Ref::SetFromRefCountableRef() and Ref::GetRefCountableRef(), respectively, for consistency.
  • testrefcount now runs a 10-second test of reference-counts in a heavily multithreaded environment, to ensure that they are thread safe.
  • Improved performance of Tuple::ShiftValuesLeft() and Tuple::ShiftValuesRight().
  • Removed re-definitions of 'true' and 'false' when compiling in C++ mode.
  • Added some missing command codes to StorageReflectConstants.py.
  • Message.py didn't handle B_INT32_TYPE fields properly when running on a 64-bit host. Fixed.
  • AddNewConnectSession() and Reconnect() now handle synchronous connect failures the same way as asynchronous connect failures, so that the calling code doesn't have to worry about two different failure modes.
  • Fixed a valgrind hit in CreateAcceptingSocket() on 64-bit platforms.
  • Fixed a buffer overflow bug in Message::AddToString().
  • Updated the header comments to fix various doxygen warnings.

New in MUSCLE 4.30 (Sep 19, 2008)

  • ChildProcessDataIO class now has SetChildProcessInheritFileDescriptors() and GetChildProcessInheritFileDescriptors() methods to control whether child processes spawned should inherit the parent's file descriptors or not. Note that these methods have no effect under Windows.
  • When receiving UDP packets, hexterm now prints out the source of the UDP packets it received (in addition to the data).
  • Added a IsNormalized() method to the Queue class.
  • Added a IsMessageDeflated() method to ZLibUtilityFunctions.h.
  • Added Message::BecomeLightWeightCopyOf(const Message &), for making lightweight copies of Messages, with shared fields.
  • Added Message::ShareName() (like CopyName() except the data isn't copied, rather only a reference is shared)
  • Added Queue::AddHeadAndGet() and Queue::AddTailAndGet() methods, for when you want to add an item to a Queue and then write to the added object directly afterwards.
  • Added an optional (retPort) argument to MessageTransceiverThread::PutAcceptFactory() so that you can now use dynamic port assignment with it.
  • PulseNode::GetPulseTime() and PulseNode::Pulse() now take a single (const PulseArgs &) argument instead of two uint64s. This makes implementing the PulseNode interface less verbose, and calling the Pulse callbacks more efficient. However, this breaks compatibility with earlier code that expects (uint64, uint64) arguments for those methods, so be sure to update your code when upgrading to this version of MUSCLE.
  • Fixed some compiler warnings under gcc (thanks to Monni for pointing these out)
  • Trying to use MUSCLE's logging system when there is not a SetupSystem object on the stack (e.g. before or after main()) is no longer a fatal error. Instead, muscle will degrade to output only to the built-in log services (stdout and/or output-to-file) when called under these conditions.

New in MUSCLE 4.28 (Aug 27, 2008)

  • Added a RefCount::IsDeeplyEqualTo() method for more in-depth comparison-by-value of the referenced items. (The regular RefCount::== operator only compares the pointers, not the items themselves)
  • Added a Directory class (util/Directory.{cpp,h}) to support directory scanning in a cross-platform-compatible fashion.
  • Added a FilePathInfo class (util/FilePathInfo.h) to support stat() functionality in a cross-platform-compatible manner.
  • ReflectServer::SetSignalHandlingEnabled() now enables/disables handling of console signal events (Ctrl-C, etc) under Win32.
  • Added implementations of GetMessageFromPool() that take a pointer and a byte-count and try to return a Message that has been unflattened from the specified byte array.
  • ChildProcessDataIO::LaunchChildProcess() now takes an optional boolean (usePty) argument that allows you to specify at runtime whether you want to use fork() or forkpty() to launch the child process.
  • Added a MUSCLE_AVOID_FORKPTY compiler flag that tells the ChildProcessDataIO class to avoid compiling in calls forkpty().
  • Made the AbstractReflectSession::EndSession() method virtual.
  • The Win32 build of MUSCLE now #includes winsock2.h instead of winsock.h.
  • The Win32 implementation of StdinDataIO wasn't handling a closed stdin connection correctly. Fixed.
  • For the Win32 build, added Microsoft's recommended work-around for the WSAECONNRESET problem with UDP sockets, as described at http://support.microsoft.com/kb/263823/en-us
  • Fixed the Hashtable and Queue classes to again compile under Visual C 6.0 (thanks to Mika Lindqvist for the patch)

New in MUSCLE 4.27 (Jul 25, 2008)

  • minichatclient.c now advertises the client's host OS on the server.
  • PrintStackTrace() is now implemented under MacOS/X (Leopard or newer).
  • PrintStackTrace() and all implementations of PrintToStream()now take an optional (FILE *) argument, so that they can nowprint to places other than stdout if you prefer.
  • The testchildprocess test program now has you specify the numberof child process instances to run. That makes it easier to testwhat happens when many child processes are launched in parallel.
  • Merged in some more of Mika Lindqvist's Haiku compatibility tweaks.
  • Hashtable::GetByDefault() with one parameter now returns its resultby reference instead of by value.
  • The Hashtable and Queue classes now keep default instances oftheir user types, to avoid having to construct temporary defaultobjects when resetting objects to their default state.
  • PrintStackTrace() now prints appropriate error messages ifit fails, instead of just failing siliently.
  • Fixed a syntax error in Hashtable::Remove(const Hashtable &)
  • Hashtable::Clear() now handles re-entrancy (from the templatizedclasses' assignment operators) correctly.

New in MUSCLE 4.26 (Jun 6, 2008)

  • Added a CheckedGetItemPointer() method to the Ref class. This method is the same as GetItemPointer(), but with an additional check so that it will safely return NULL if the "this" pointer is NULL.
  • Added a "assumeDefaultValue" argument to the NumericQueryFilter, StringQueryFilter, and RawDataQueryFilter classes. This argument lets you specify that in the event that a Message doesn't contain the data item the QueryFilter wants to compare against, a default value should be compared against instead.
  • Added a HashCode() method to the Ref class, for consistency.
  • ChildProcessDataIO::GetChildProcessID() is now implemented under Windows as well.
  • Added two new conditional defines to MuscleSupport.h: MUSCLE_USING_OLD_MICROSOFT_COMPILER, which is defined when compiling under VC 6 or earlier, and MUSCLE_USING_NEW_MICROSOFT_COMPILER, which is defined when compiling under VC .net(2003) or later. These make managing Microsoft's bug circus a bit a easier.
  • Fixed the Ref class to compile under MSVC2005 again.
  • Fixed the setsockopt()/getsockopt() calls in NetworkUtilityFunctions.cpp so that they again compile under Windows.
  • Merged in Mika Lindqvist's patches so that muscle compiles properly under Haiku.

New in MUSCLE 4.24 (Apr 29, 2008)

  • If MUSCLE_USE_LIBRT and _POSIX_MONOTONIC_CLOCK are defined, GetRunTime64() and Snooze64() will now use librt's high-resolution functions (clock_gettime() and clock_nanosleep()) instead of the older vanilla POSIX functions. This can provides higher resolution timing on platforms that support librt.
  • Added a new ExecuteSynchronousMessaging() virtual method to the AbstractMessageIOGateway class, and some associated hook/callback methods. This method lets you easily do synchronous/RPC-style "function calls" across the gateway's socket, passing in one or more Message objects as the "arguments", and receiving one or more Messages as "results".
  • MessageIOGateway now overrides ExecuteSynchronousMessaging(), IsStillWaitingForSynchronizedReply(), and SynchronousMessageReceivedFromGateway() so that when you call ExecuteSynchronousMessaging() on it you will get proper RPC function-call semantics.
  • Added an IsReadyToAcceptSessions() virtual method to the AbstractReflectSessionFactory class. Subclasses can override this method to return false if they don't want to accept any more connections for a while.
  • Added an IsConnected() method to the AbstractReflectSession class, to make it easier to check if a given session is currently connected to anything or not.
  • Added an XorDataIO class to the dataio folder. XorDataIO XOR's all the data going through it, before forwarding the method call to its held child DataIO object.
  • Added a MutexGuard class that you can put on the stack to automatically lock/unlock a Mutex via its ctor/dtor.
  • Added versions of ReadZipFile() and WriteZipFile() that take a DataIO reference instead of a file name. That way you can read zip files over the network, through custom filters, and so on, if you want to. zlib/ZipFileUtilityFunctions.{cpp,h}.
  • ReadZipFile() now has an optional second argument called (loadData). Setting it false will cause ReadZipFile to only read in the file names and uncompressed file lengths, but not actually read or uncompress the file data. This is useful if you just want to quickly check the zip file's contents without actually unpacking everything.
  • Updated testzip.cpp to accept an optional "namesonly" command line argument, which will set (loadData) to false in its ReadZipFile() call, as described above.
  • Added a GetNetworkInterfaceAddresses() function, as an easier-to-use alternative to GetNetworkInterfaceInfos().
  • Made AbstractReflectSession::IsConnectingAsync() public.
  • Moved Snooze64() from NetworkUtilityFunctions.cpp to SetupSystem.cpp, and moved its function declaration from NetworkUtilityFunctions.h to TimeUtilityFunctions.h.
  • Joel Lucsy reported a bug in FlattenToDataIO() that would cause the last four bytes of the flattened buffer not to be written to the DataIO object. Fixed.
  • Updated zlib's included VC project files to reference zconf.h in its new location (zlib/win32/zconf.h) so that they now work again.

New in MUSCLE 4.22 (Mar 5, 2008)

  • Added an IsDaemonProcess() function that returns true iff the current process was created via SpawnDaemonProcess() or BecomeDaemonProcess().
  • Added a AssembleBatchMessage() convenience function to MiscUtilityFunctions.{cpp,h}. It's useful for creating a PR_COMMAND_BATCH Message from zero or more other Messages.
  • The NestCount class will now cause an assertion failure if Decrement() is called when it is already at zero... that should never happen in correct code.
  • Added an optional (numColumns) argument to the PrintHexBytes() utility function.
  • Added a templatized bit-chord class, support/BitChord.h.
  • Added ReadData() and WriteData() functions to NetworkUtilityFunctions.{cpp,h}. These are the same as SendData() and ReceiveData(), except that they call read() and write() instead of send() and recv().
  • Replaced the PrintHexBytes() implementation with the superior one from hexterm.cpp.
  • Added a GetWithDefault() convenience method to the Hashtable class.
  • Moved the Win32 version of zconf.h from zlib/zlib to zlib/zlib/Win32, so that it wouldn't show up in SVN as modified whenever the configure script modified it.
  • Changed the default value of MUSCLE_POOL_SLAB_SIZE to 4 kilobytes, to reduce memory overhead somewhat. This value coincides nicely with the most common memory page size.
  • The POSIX implementation of RS232DataIO was broken, because it was trying to use SendData() and ReceiveData() on the serial port's (non-sock) fd. Changed it to call ReadData() and WriteData() instead.
  • Rewrote the Unix implementation of ChildProcessDataIO to call forkpty() instead of doing everything by hand. This makes the implementation much simpler and more reliable, although of course it will only work on systems that have forkpty() available.
  • ChildProcessDataIO now closes any forked file handles in the child process before calling exec().
  • Made the PacketTunnelIOGateway parsing more flexible; duplicate packets no longer break a logical stream.
  • Removed several files from the zlib/zlib folder that are meant to be generated by the configure script.