This file contains the version history/change log for this software. key: - new feature * bug fixed o other 9.36 - Released 3/6/2024 - Added GetMostRecentInputTimeStamp() and GetMostRecentOutputTimeStamp() methods to the AbstractReflectSession class - Added a GetMostRecentAcceptTimeStamp() method to the ReflectSessionFactory class. - Added a GetAcceptCount() method to the ReflectSessionFactory class. - PrintSessionsInfo() now includes text describing how recently each session has sent or received data. - PrintFactoriesInfo() now includes text describing how recently each factory has accepted an incoming TCP connection, and how many connections the factory has received so far. - Added a GetClientDescriptionString() virtual method to the AbstractReflectSession class to support more-useful debug output. - Added a GetSocketBindAddress() function to NetworkUtilityFunctions.h for querying where a socket is bound to on the local machine. o Renamed GetPeerIPAddress() to GetPeerAddress(), and changed it to return an IPAddressAndPort instead of returning an IPAddress and also using a separate (optPort) argument. o Tweaked zlib/zlib/zconf.h so that the gzlib files can build successfully even if ./configure wasn't called in the zlib/zlib folder first. o SocketMultiplexer::RegisterSocket() now emits an error message to the log if a file descriptor is too large to pass to FD_SET(). * Updated build instructions to specify cmake instead of Visual Studio 9.35 - Released 2/14/2024 - Added an optional (optRunAsUser) argument to the various process launch methods in ChildProcessDataIO. - Added convenience constructors to the IPAddress class that take an in_addr or in6_addr as an argument. - Added convenience constructors to the IPAddressAndPort class that take a sockaddr_in or sockaddr_in6 as an argument. - Added WriteToInAddr() and WriteToIn6Addr() convenience methods to the IPAddress class. - Added WriteToSockAddrIn() and WriteToSockAddrIn6() convenience methods to the IPAddressAndPort class. - Added convenience overloads of the SendDataUDP() and ReceiveDataUDP() functions that take an IPAddressAndPort as their source/destination argument. - Added method IPAddress::IsIPv6LinkLocal(). o Changed ChildProcessDataIO::ChildProcessReadyToRun() to be protected instead of public. o Removed ip_address typedef; use IPAddress instead. o Tweaked Inet_NtoA() so that when called with the (preferIPv4) flag, it will return the invalid/all-zeroes IP address string as "" rather than "::". * Updated TarFileWriter to handle it a little more elegantly when a file's length changes while the tar data is being written out to a non-seekable DataIO. * Fixed a bug in the Ref class that would cause a NULL Ref's status-string to be returned as "OK" rather than "NULL Ref" * BitChord::SetByte()'s second argument was the wrong type. Fixed. 9.34 - Released 12/18/2023 - Added an optional localnicip=local.nic.ip.address argument to hexterm, to better support sending IPv4 multicast packets. - Added a B_SHUTTING_DOWN error code, useful for returning from Thread::MessageReceivedFromOwner() overrides if there isn't any real error but the internal thread is exiting on request. - Added a templated GetConstRefToDefaultObjectForType() convenience function to util/RefCount.h - Added a GetHardLinkCount() method to the FilePathInfo class. o Modified IsRegexToken() to return false for '-', since hyphens aren't meaningful except in the context of "character class" regex tokens (which will get escaped anyway). o Replaced the IsHosed() and SetHosed() methods of the AbstractMessageIOGateway class with more descriptive methods GetUnrecoverableErrorStatus() and SetUnrecoverableErrorStatus(). 9.33 - Released 10/30/2023 - Added FromHexString() and FromBinaryString() methods to the BitChord class, to complement the ToHexString() and ToBinaryString() methods. - Added a Queue::IsIndexValid(uint32) convenience-method. - Updated the Queue::Remove*() methods to use std::move() when possible. - Updated the Hashtable::Remove*() methods to use std::move() when possible. - Added IsAtStart() and IsAtEnd() convenience-methods to the HashtableIterator class. - The snoopsharedmem tool now support an optional (maxBytesToPrint) argument, in case you only want to see the header of the region. o Removed obsolete references to TARGET_PLATFORM_XENOMAI. o Updated the captive zlib library to the current GitHub version, to avoid "function declaration without a prototype is deprecated" compiler warnings. * Fixed the LogTime() and LogPlain() macros so that they compile when called from a different namespace. * Changed ImmutableHashtablePool::GetWithAux() to repurpose an existing table (if possible) while adding an item, as well as when removing one. 9.32 - Released 9/8/2023 - Added a -DWITH_HELGRIND option to CMakeLists.txt to enable causality annotations in the reference-counting of RefCount.h so that helgrind doesn't give false-positive warnings when analyzing an execution of this code for race conditions. - Added MUSCLE_CONSTEXPR tag to trivial constructors and methods of various POD-like utility classes. - Added MUSCLE_CONSTEXPR_17 macro, for places where a constexpr tag is useful but only allowed in C++17 or later. o Updated PythonUtilityFunctions.h to use a forward-declaration instead of #include-ing Python.h directly, to avoid potential namespace-collisions between Python and Qt. * Applied fixes for various minor issues flagged by pvs-studio-analyzer. * Changed SignalMultiplexer's received-signal-counters to be AtomicCounters rather than uint32 to avoid helgrind complaints when a signal is handled. * The ObjectPool constructor now calls GetDefaultObjectForType() on its object-type and the associated Ref-types, to ensure that the static singleton is initialized while the process is still in a single-threaded state. * IsMessageDeflated() now takes a ConstMessageRef rather than MessageRef. * Fixed a pointer-type-mismatch issue that could cause unnecessary compile-time errors in the templated version of Hashtable::Remove() 9.31 - Released 6/14/2023 - Added an IsFileOpen() method to the GZDataIO class. - Modified the Hashtable class so that HashtableIterators are only registered in the iterators-list if they are actually pointing at a valid HashtableEntry. - ParseConnectArg() and IPAddressAndPort::SetFromString() now support an alternate port-syntax that doesn't require brackets, to get around osascript's command-parsing limitations. E.g. you can now specify "::1_port_1234" instead of "[::1]:1234" - Added convenience PODHashFunctor specializations (for QSize, QPoint, and QRect) to QMuscleSupport.h o Increased the Snooze64() time in testatomicvalue's writer thread to 10mS as it appears that 1mS snoozes were being rounded down to zero. o Added MUSCLE_NODISCARD tag to the String and IPAddressAndPort classes. o Increased the default value of AtomicValue's ATOMIC_BUFFER_SIZE template argument to 8. * Fixed code that was passing NULL as an argument to %s in printf() or LogTime(). Thanks to Ruurd Adema for pointing out that doing that is undefined behavior. * Changed Hashtable::_iteratorThreadID to be a std::atomic<> to avoid potential undefined behavior in multithreaded scenarios. * Fixed AtomicValue class to use bitmasks instead of modulo and only support powers-of-two array sizes. * Fixed the handling of InterlockedCompareExchange()'s return value in the AtomicValue class. 9.30 - Released 4/28/2023 - Tagged the constructor of the MutexGuard class (and friends) as MUSCLE_NODISCARD so the compiler will warm about anonymous guards. - Tagged ObjectPool::ObtainObject() with MUSCLE_NODISCARD. - Added MUSCLE_NODISCARD to all the functions and methods that it wouldn't make sense to call without examining their return value. - Added MUSCLE_NODISCARD to various concrete classes (String, Queue, Hashtable, IPAddress, etc) that shouldn't be ignored when used as return values. o Renamed String::Append() to String::WithAppend(). o Renamed String::Prepend() to String::WithPrepend(). o Renamed String::AppendWord() to String::WithAppendedWord(). o Renamed String::PrependWord() to String::WithPrependedWord(). o Renamed String::Trim() to String::Trimmed(). o Renamed String::Pad() to String::PaddedBy(). o Renamed String::Indent() to String::IndentedBy(). o Removed DEFAULT_MUSCLE_ROUTING_FLAGS_BIT_CHORD, and rewrote the routing flags to use the BitChord class. o Rewrote testnagle.cpp to include a unit-test for automated testing. o Updated function declarations in regex captive library to avoid compiler warnings. o Updated the unit tests so none of them takes more than 5 seconds to complete when done as part of a CMake "make test" pass. * Fixed logic error in testgateway.cpp. * MUSCLE_NODISCARD is now defined as a no-op when compiling C code, to avoid breaking the build under C compilers that say they support C23 but nevertheless don't grok [[nodiscard]] yet. 9.25 - Released 4/7/2023 - Rewrote String::WithReplacements(const Hashtable &) to only scan the input string once, instead of once per key. - Added a String::Replace(const Hashtable &) method. - Added a ReplaceAllItems() convenience-method to the Queue class. - Added MUSCLE_NO_DISCARD keyword, and applied it to the Ref and ConstRef classes and to the status_t and io_status_t types, so that calls ignoring these return values will generate compile-time warnings. - Added a TruncateToLength() convenience method to the ByteBuffer class. - Added a PR_NAME_KEEPALIVE_INTERVAL_SECONDS parameter so clients can tell muscled to send a PR_RESULT_NOOP every (so many) seconds to verify TCP connectivity on an otherwise idle connection. - DefaultFileLogger now calls GetFileAttributeA() on the log file (at most once per second) in order to get Windows to update the log file's file-size entry in a semi-timely manner. o Removed DataIO::GetReadByteTimeStamp() as it wasn't being used. o CloseSocket() now prints an error message if its call to close() fails. * GetProcessMemoryUsage() now returns more accurate values. * Fixed a number of broken hyperlinks in the MUSCLE-by-example mkdocs. 9.24 - Release 3/20/2023 - Added a CMakePresets.json file for quick specification of minimal (i.e. library-only) or full (i.e. including unit-tests) builds. - Added a CMAKEOPTIONS.txt file to describe the options available for building MUSCLE via cmake. o Moved the non-unit-test executables out of the "test" folder and into their own new/separate "tools" folder. o Renamed BUILDOPTIONS.txt to COMPILEROPTIONS.txt * Modified AbstractReflectSession::Reconnect() to not fail if CreateDefaultSocket() return a NULL reference. * The Python3 implementation of message.py wasn't encoding non-ASCII utf8 strings correctly when flattening a Message. Fixed. * ZLibCodec::Inflate() would fail when inflating a compressed zero-byte buffer. Fixed. 9.23 - Release 2/24/2023 - Added a -DWITH_THREAD_SANITIZER=ON option to the CMakeLists.txt. - Added a -DMUSCLE_NUM_RESERVED_HIGH_BITS_IN_POINTERS flag to specify how many of the most-significant-bits of a pointer are reserved for system use. This value defaults to 16 for 64-bit Android systems (to account for Android's MTE feature) and to 0 on everything else. - Added a _registeredSubscribersMutex to the ICallbackMechanism class so that it can handle unusual dispatching cases more gracefully. - Added a runtests.sh script to tests folder. This script can be run to quickly execute all tests and report any detected regressions. - Added add_test() directives to test/CMakeLists.txt to enable CTest. o Renamed -DMUSCLE_AVOID_BITSTUFFING to -DMUSCLE_AVOID_TAGGED_POINTERS since the latter is a more commonly-used term. o Changed the default setting of the WITH_TESTS option to OFF in CMakeLists.txt * GetNetworkInterfaceinfos() is now implemented for Android (API level 24 or later). * SharedMemory.cpp now compiles under Android (pre API level 26) although its methods will return B_UNIMPLEMENTED if called. * GetNetworkInterfaceInfos() now returns B_UNIMPLEMENTED when called from an OS that it doesn't have an implementation for. * Applied some Android build fixes as suggested by Ruurd Adema. * SetFileLogLevel() was broken. Fixed. * Avoid including sem.h when MUSCLE_FAKE_SHARED_MEMORY is defined. * Fixed a minor bug where the socket's assigned network interface index might not get restored when after sending a zero-byte multicast UDP packet. 9.22 - Released 2/2/2023 - Modified Queue::InternalizeIndex() to use subtraction instead of modulo, for a 3x efficiency gain. - Added a MUSCLE_NOEXCEPT keyword that expands to noexcept under C++11 or later, or to nothing under C++03 - Added MUSCLE_NOEXCEPT tags to the SwapContents() methods and move-constructors/operators that can make that guarantee. - Added a MatchesNodeNameQueryFilter class, to support query filtering against DataNode-names. - Added DataNode::SetNodeName() - Added a WITH_IPV6=OFF option to the CMakeLists.txt for easier building of MUSCLE in IPv4-only mode. - Added a "shareport" argument to hexterm to enable UDP port-sharing. - Added an IsBroadcast() method to the IPAddress class. - Added GetStatus() and SetStatus() methods to the Ref/ConstRef/DummyRef/DummyConstRef classes, so that when they are returned in a NULL state they can tell you why they aren't set. - Added BooleansToBitChord() convenience-functions to PointerAndBits.h - Updated PointerAndBits to be able to use the high bit in a pointer as well as the low bit(s). - Updated the captive zlib library to v1.2.13. o Replaced the PointerAndBool.h header (and class) with a new PointerAndBits.h header (and class) that does the same thing, but in a simpler, more generalized fashion. * Fixed broken UDP support in hexterm when -DMUSCLE_AVOID_IPV6 was set as a compiler-flag. * Renamed SOCKET_FAMILY_IPV6 to SOCKET_FAMILY_IPV6_IS_DISABLED when -DMUSCLE_AVOID_IPV6 is set, to avoid potential runtime bugs. 9.21 - Released 1/13/2023 - Added @tparam Doxygen tags for any template-arguments that the calling code might need to specify explicitly. - Enabled tagfile generation in muscle.dox. - Added a DataIO::ReadFullyUpTo() convenience-method to handle reading (up to n) bytes or (until EOF), whichever comes first. - Added error code B_END_OF_STREAM to allow Read()-type methods to unambiguously specify that the reason they are returning an error is because they have reached EOF/EOS. o Changed DataIO::ReadFully() and DataIO::WriteFully() to return status_t instead of uint32. o Removed the C APIs from the Doxygen output. o Auto-updated the muscle.dox file to the latest Doxygen version. * Fixed several issues to make Doxygen's output more useful. * Fixed some compiler warnings in the captive regex library. * Fixed the namespacing of the DoxyTemplates header so that Doxygen generation works with the newest Doxygen version. * Updated a number of out-of-date Doxygen comments. 9.20 - Released 12/30/2022 - Updated NetworkUtilityFunctions.cpp to better support "real" IPv4 sockets (previously it assumed that IPv4 traffic would be handled using IPv6 sockets and IPv4-mapped IPv6 addresses, but that approach doesn't give 100% compatibility in all cases) - Added a GetSocketFamily() method to the Socket class. - Added an optional (socketFamily) argument to CreateUDPSocket(). - Added IsOK(io_status_t &) and IsError(io_status_t &) method overrides to the io_status_t class. - hexterm now instantiates a genuine IPv4 socket for use with IPv4 multicast traffic. - Tweaked gz*.c includes to compile without a configuration step. - Added input-data-timestamping (including a PR_NAME_DATA_TIMESTAMP field and SetReceiveTimestampingEnabled() and GetReceiveTimestampingEnabled() methods) to the RawDataMessageIOGateway class. - Added SetLogLevelThreshold() and GetLogLevelThreshold() arguments to the LogCallback class so that any LogCallback can now specify what log-levels it is (or is not) interested in. - Added templated overloads of Message::FindFlat(), Message::FindTag() Message::GetFlat(), and Message::GetTag() that take any type of Ref as an argument, so calling code no longer has to pass in a generic RefCountableRef or FlatCountableRef and then do the necessary downcasting separately afterward. - Message::FindTag() now takes a ConstRefCountableRef as an argument rather than a RefCountableRef, for better flexibility. - Added templated overloads of Message::AddFlat(), PrependFlat(), ReplaceFlat(), AddTag(), PrependTag(), and ReplaceTag() so that the calling code no longer has to do manual upcasting of typed FlatCountableRef or RefCountableRef objects before calling them. - Added ConstMessageRef overloads of InflateMessage() and DeflateMessage(). - Added a ConstMessageRef-returning overload of Message::FindMessage(). o Removed the ByteBufferRef-specific *Flat() methods from the Message class, since we now have more general templatized methods that offer the same semantics for any type. o SocketMultiplexer::WaitForEvents() now returns an io_status_t rather than an int, for better error-reporting. o Merged the IPv6 and IPv4 versions of AddSocketToMulticastGroup() and RemoveSocketFromMulticastGroup() so that a single implementation can work on either type of socket. o Renamed SetSocketMulticastSendInterfaceAddress() and GetSocketMulticastSendInterfaceAddress() to SetIPv4SocketMulticastSendInterfaceAddress() and GetIPv4SocketMulticastSendInterfaceAddress(), respectively, and made them available even when -DMUSCLE_AVOID_IPV6 isn't set. o Renamed Log() to LogPlain(). o Made LogTime() and LogPlain() into macros so that their arguments will not be evaluated unless the logging-threshold-test passes. o Improved error reporting in the ReflectServer event-loop. o Removed the functions from TimeUnitConversions.h that take (struct timeval &) as their argument, since they weren't being used. o Removed SetConsoleLogLevel() and GetConsoleLogLevel() from the DefaultConsoleLogger class, in favor of the new equivalent methods in the LogCallback base class. o Removed SetFileLogLevel() and GetFileLogLevel() from the DefaultFileLogger class, in favor of the new equivalent methods in the LogCallback base class. o Renamed muscle's private namespaces to muscle_private. o Replaced long with int32 in some I/O support functions. o The default ByteBufferPool now clears the IMemoryAllocationStrategy field of any ByteBuffer it recycles (after freeing its memory), to avoid polluting the pool with user-installed strategies. o Ref::SetFromRefCountableRef() now returns B_TYPE_MISMATCH on failure rather than B_BAD_ARGUMENT. o Removed the two-argument ConstRef and Ref "pseudo-constuctors" and added instead a DowncastTo() method, to make Ref-downcasting operations self-documenting. o Changed ITraversalPruner::MatchPath() and CreateObjectFromArchiveMessage() to take ConstMessageRef as an argument rather than MessageRef. o Changed StorageReflectSession::SetDataNode(), InsertOrderedData(), InsertOrderedChildNode(), and GetNewDataNode() to take ConstMessageRef as an argument rather than MessageRef. o Changed DataNode to hold a ConstMessageRef rather than a MessageRef. o Changed StorageReflectSession::NotifySubscribersThatNodeChanged() and StorageReflectSession::NodeChanged() to pass a ConstMessageRef rather than a MessageRef. o ByteBuffer::ReleaseBuffer() now returns (uint8 *) instead of (const uint8 *). * Fixed MLOG_ON_ERROR and friends to be usable with io_status_t. * ExpandLocalhostAddress() no longer expands IPv6 loopback addresses. * UDPSocketDataIO::ReadFrom() would call SetSourceOfLastReadPacket() even when no packet had been read, clearing that field. Fixed. * Some functions in MuscleSupport.h were unintentionally being declared outside the muscle namespace. Fixed. 9.10 - Released 12/10/2022 - Rewrote the non-Windows implementation of muscleSprintf() to call vsnprintf() instead of sprintf(), to avoid compiler warnings about sprintf() being insecure. - Instrumented the non-Windows implementation of muscleSprintf() with MUSCLE_PRINTF_ARGS_ANNOTATION_PREFIX so that the compiler will warn about calls to muscleSprintf() with the wrong format specifiers. - Added an io_status_t class to represent the result of an I/O operation. An io_status_t contains both a status_t and an int32 byte-count. - Added a MUSCLE-by-example page for the status_t class. - Added MTALLY_BYTES_OR_RETURN_ON_IO_ERROR() and MTALLY_BYTES_OR_RETURN_ON_IO_ERROR_OR_BREAK() macros to MuscleSupport.h. o Changed the return-types of the NetworkUtilityFunctions that previously returned (int32/byte-count-or-negative-1), aka SendData(), ReceiveData(), SendDataUDP(), ReceiveDataUDP(), ReadData(), and WriteData() to return a more informative io_status_t instead. o Changed the DataIO::Read() and DataIO::Write() methods to return io_status_t instead of int32. o Changed the PacketDataIO::ReadFrom() and PacketDataIO::WriteTo() methods to return io_status_t instead of int32. o Simplified the implementation of GetDefaultObjectForType() back to one that compile under any version of C++. We'll rely on the optimizer to do the right thing, rather than SFINAE. o Modified Directory::SetDir() to return a static status_t value rather than B_ERRNO, to avoid potential static-initialization ordering problems on pre-C++11 compilers. o tagged status_t as a MUSCLE_FINAL_CLASS. o Replaced the MAKETYPE(x) macro with a MakeWhatCode() function. * Updated message_transceiver_thread.py to catch and ignore any EAGAIN exceptions generated by send() on a notification-socket. * Fixed a spurious assertion failure in SimulatedMulticastDataIO. * Changed some code to return B_IO_ERROR instead of B_ERRNO if fread() or fwrite() fails, since those functions are not guaranteed to set errno when they fail. * Fixed a bug that would cause GetEnvironmentVariableValue() to sometimes return garbage strings under Windows if the environment variable did not exist. * Added missing Doxygen parameter documentation for various macros declared in MuscleSupport.h. * Fixed a number of broken hyperlinks in the MUSCLE-by-example docs. 9.01 - Released 11/18/2022 - Added a WritePaddingBytesToAlignTo(uint32 alignSize) convenience-method to the CheckedDataFlattenerHelper and DataFlattenerHelper classes. - Added a SeekPastPaddingBytesToAlignTo(uint32 alignSize) convenience-method to the DataUnflattenerHelper class. - Added DataUnflattener ctor and SetBuffer() calls that take a ByteBufferRef, for convenience. - Added a GetEnvironmentVariableValue() convenience function, to avoid calling getenv() directly from user code. - Added %p (aka process ID) to the set of tokens expanded by HumanReadableTimeValues::ExpandTokens(). - DefaultFileLogger::EnsureLogFileCreated() now tries a little harder: if it can't create a log file with the given file name, it will try up to 10 variants of the file name in the hopes of coming up with a file name that is unique and can be created. - Added a IsBitIndexValid() convenience-method to the BitChord class. - Added MUSCLE_CONSTEXPR_OR_CONST macro to expand to "constexpr" if possible, or "const" otherwise. - GetDefaultObjectForType() now uses constexpr to avoid on-demand initialization, when -DMUSCLE_USE_CPLUSPLUS17 is defined. - CMakeLists.txt now automatically specifies -DMUSCLE_USE_PTHREADS if building on POSIX for C++03, and WITH_THREADS is ON. - LogTime() calls now emit printf-style format-usage warnings when compiled with g++ or clang++. - Added INT16_FORMAT_SPEC_* macros, for completeness. o PODSwapper now calls std::swap() rather than reimplementing it. * Moved the definitions of the B_* error-codes out of SetupSystem.cpp and into MuscleSupport.h, so that Clang's Static Analyzer can see what values they contain and generate better output. * Generation of the random number that %r expands to is now actually random (not just calling rand()) (in C++11 or newer). * Renamed several of the longer mkdocs examples folder names to avoid hitting Windows' 260-character path limit. * Fixed a potential uninitialized-memory-read in the String class's GetLevenshteinDistance() method. * Fixed the CMakeList.txt files in the sub-folders to use the inherited CMAKE_CXX_STANDARD setting rather than forcing C++11. * GetCurrentThreadID() is no longer compiled if -DMUSCLE_SINGLE_THREAD_ONLY is specified. 9.00 - Released 10/27/2022 - Added a MUSCLE_MAXIMUM_NODE_DEPTH constant that limits how deep the MUSCLE node-tree may become, to prevent stack-overflow attacks. Defaults to 100. - Added DataFlattener and DataUnflattener classes to allow for safer flattening/unflattening of data to/from byte-buffers. - Added an UncheckedDataUnflattener class, for better efficiency when the calling code has already done its own bounds-checking. - Added a CheckedDataUnflattener class, for better calling code that wants to use a dynamically-growing output buffer. - Added support/EndianConverter.h to allow templating over big/little/native endian-encoding strategies. - Added pages for DataFlattener and DataUnflattener APIs to the muscle-by-example documentation. - Adding -DMUSCLE_USE_BIG_ENDIAN_DATA_FOR_EVERYTHING to your compile line will tell MUSCLE to use big-endian data format for all of its data. Note that doing so will break interoperability with all existing MUSCLE builds! - Adding -DMUSCLE_USE_NATIVE_ENDIAN_DATA_FOR_EVERYTHING to your compile line will tell MUSCLE to use native-endian data format for all of its data. Note that doing so will break compatibility with different-endian CPUs! o Changed the PseudoFlattenable::Flatten() and Flattenable::Flatten() methods to take a second argument (flatSize) for better runtime error-checking. o Changed the PseudoFlattenable::Unflatten() and Flattenable::Unflatten() methods to take a (DataUnflattener &) as an argument rather than a raw pointer, for better caller/callee cooperation. o Changed Message::TemplatedFlatten() to use a DataFlattener as an argument. o Changed Message::TemplatedUnflatten() to use a DataUnflattener as an argument. o Removed the SetEndianFlag(), Append*(), Write*(), Read*() methods from the ByteBuffer class. Use the new DataFlattener/DataUnflattener classes instead. o Refactored the StringTokenizer class's constructors to take a single (optSepChars) argument instead of separate arguments for hard and soft separator characters. o Made the calculation of DataNode depths more efficient. o Removed Flattenable::WriteData() and Flattenable::ReadData() methods (since DataFlattener/DataUnflattener do it better). o Replaced most calls to B_LENDIAN_*_TO_HOST() and B_HOST_TO_LENDIAN_*() with calls to DefaultEndianConverter's Import() and Export() methods, to allow MUSCLE to be built in big-endian mode. o Changed the PseudoFlattenable class to be templatized, and added methods to it so all the helper methods declared in the Flattenable interface are also available in the PseudoFlattenable interface. o Refactored the ZLib-support classes in muscle/zlib so that they no longer include any zlib-headers from their header files. * Modified Snooze64() to call clock_nanosleep() under Linux, and to call nanosleep() when -DMUSCLE_USE_LIBRT is defined. * Changed all the #include "zlib/zlib/zlib.h" directives to #include "zlib.h" to avoid using the captive zlib headers together with any system-supplied zlib implementation (which might be different) * Fixed a bug that could cause ZLibDataIO::WriteAux() to to into an infinite recursion if zlib's deflate() errored out. * Fixed a bug in MessageIOGateway that could cause it fail to report how many bytes it had sent or received, if an I/O error occurred later on in the same call to DoInput() or DoOutput(). 8.62 - Released 9/22/2022 - Added a Hashtable::ComputeInvertedTable() convenience-method. - Added a Hashtable::ComputeValuesHistogram() convenience-method. - Updated server/Makefile and test/Makefile to compile Universal binaries under MacOS/X, if the BUILD_UNIVERSAL_BINARIES environment variable is set. - Updated the captive zlib library to v1.2.12. o Rewrote Hashtable::InsertIterationEntryInOrder() to be simpler and more efficient in most cases. * Hashtable::Clear() wasn't updating registered HashtableIterators properly. Fixed. * python3/message.py was calling deprecated method array.fromstring() when it should be calledin array.frombytes(). Fixed. * python3/message.Flatten() now handles it properly when passed a string as a raw data-item. 8.61 - Released 8/2/2022 - Added a GetMTU() method to the NetworkInterfaceInfo class. - Added a BitChord::WithBitSetTo() convenience method. - Added a snoopsharedmem program to the tests folder. - Added an erasesharedmem program to the tests folder. - Improved the error codes returned by methods in the SharedMemory class. - GetSystemPath(SYSTEM_PATH_USERHOME) now falls back to calling getpwuid() on POSIX systems, if the getenv("HOME") approach fails. - Added a WaitConditionCallbackMechanism utility class. - Added an AtomicValue class to support lock-free variable-sharing. - Added a SpinLock class. - Added a PR_RESULT_NOOP code to the enum in StorageReflectConstants.h - Added testatomicvalue.cpp to test/verify the AtomicValue class. o Calling Write() on a UDPSocketDataIO with zero destinations no longer results in an error-return; rather the data is discarded and Write() returns success. o Updated copyright notices at the tops of files. o Removed trailing spaces from all source files. o Suppressed a compiler warning when compiling with OpenSSL support enabled. o Modified Queue::InsertItemAt() and Queue::InsertItemsAt() to allow insert-positions greater than the size of the Queue. Calls like that will append the item(s) to the end of the Queue. * Added psapi.lib to Qt .pro files for Windows, so Qt programs can link. * Fixed the Makefile in tests to compile testsharedmem by default. * Added some missing build-executable directives to tests/CMakeLists.txt. 8.60 - Released 5/28/2022 - Added a WaitCondition class for easy Wait()/Notify() functionality. - Updated the Thread class to use a WaitCondition object as a fallback if (useMessagingSockets) is passed to the constructor as false. - Added WITH_CPLUSPLUS11=OFF and WITH_CPLUSPLUS17=ON options to the CMakeLists.txt file. - Added a WITH_PTHREADS=ON option to the CMakeLists.txt file. - Added B_IO_READY to the set of declared status_t error-values. - Added example programs and documentation for the new WaitCondition class to the muscle-by-example folder. o Updated Thread::WaitForNextMessageFromOwner(), Thread::GetNextReplyFromInternalThread(), and MessageTransceiverThread:: GetNextEventFromInternalThread() to return status_t instead of int32. o Rephrased the message printed when the crash-signal-handler executes. o Swapped the ordering of arguments to the Thread class's constructor. * Added code to JUCECallbackMechanism::handleAsyncUpdate() to work around a bug(?) in JUCE where handleAsyncUpdate() could be called re-entrantly in certain circumstances. * qt_muscled_browser's "connected_at" field was being generated using the wrong clock (GetRunTime64() instead of GetCurrentTime64()). Fixed. * Fixed a bug in StorageReflectSession::NodeChanged() that could cause subscription-results to be returned upon the creation of nodes that should have been filtered out by the subscription's QueryFilter. 8.52 - Released 4/7/2022 - Added testtar.cpp to the tests folder to test the TarFileWriter class. - Added a assertion-check in the ThreadSetupSystem constructor to make sure it is being declared in the main thread. - Added a assertion-check in the CompleteSetupSystem destructor to make sure all declared CompleteSetupSystems are destroyed in LIFO order. o Removed the (useGZip) argument from the ZLibDataIO constructors and instead created a separate GZLibDataIO subclass to instantiate when .gz-compatible output is desired. o Updated muscle.dox to suit Doxygen 1.9.3's taste. * CompleteSetupSystem's initial-memory-usage value is now set only by the first instance of CompleteSetupSystem. * sizeof(ReflectServer) and sizeof(MessageTransceiverThread) no longer change depending on whether MUSCLE_ENABLE_SSL is defined or not. * sizeof(MessageIOGateway) and sizeof(MiniPacketTunnelIOGateway) no longer change depending on whether MUSCLE_ENABLE_ZLIB_ENCODING is defined or not. * Fixed a bug in ZLibDataIO.cpp that could cause deflated data not to be fully written out to the child DataIO object in some cases. * Fixed a race condition that could cause Thread::SetThreadPriority() to occasionally fail with a "no such process" message. * Fixed some #ifdefs in SetupSystem.h and ThreadLocalStorage.h that assumed that MUSCLE_USE_PTHREADS and MUSCLE_USE_CPLUSPLUS11THREADS defines were mutually exclusive, when they aren't. * Updated various programs in the tests directory to still compile (with reduced functionality) even if MUSCLE_ENABLE_ZLIB_ENCODING isn't specified. * Fixed #include path in Win32FileHandleDataIO.cpp 8.51 - Released 3/15/2022 - Added a SetConsoleLogToStderr(bool) to make it easier to direct LogTime()'s output to stderr rather than stdout if desired. - Added a "logtostderr" option for HandleStandardDaemonArgs() to detect and call SetConsoleLogToStderr(true) in response to. - Added support/Archivable.h as an abstract interface to represent an object that can have SetFromArchive() and SaveToArchive() called on it. - Added an optional second argument to the ZLibDataIO constructor that allows it to handle .gz-file-format-compatible data. - Added "zlib" and "gzip" flag-arguments to hexterm. o Updated TarFileWriter class to be RefCountable o ZLibDataIO now subclasses DataIO rather than ProxyDataIO, since it isn't actually seekable or packetizable. o Fixed several deprecation-warnings when compiling under MacOS12. o QueryFilter now subclasses Archivable. * Updated PseudoFlattenable methods in the BitChord class to be static rather than const, so they can be called without an instance. * Fixed a regression that would cause MessageTransceiverThread to fail to connect an outgoing session if the session's target was specified via hostname-string instead of IPAddressAndPort. * Removed the default-value for the template-argument of ImmutableHashtablePool::DropAllCacheEntriesContainingAnyOfTheseKeys() since it's unnecessary and ancient (C++03) compilers don't like it. 8.50 - Released 1/31/2022 - Added two-argument versions of the GetAndMoveToFront() and GetAndMoveToBack() methods in the Hashtable class. o muscleSwap() now calls through to std::swap() when possible. o Modified various method-calls (e.g. AddNewConnectSession(), Connect(), ConnectAsync()) that took an IPAddress and a port as separate arguments to take an IPAdddressAndPort argument instead. o Removed AbstractReflectSession::GetAsyncConnectIP() and AbstractReflectSession::GetAsyncConnectPort(). Call AbstractReflectSession::GetAsyncConnectDestination() instead. o Replaced setMargin() with setContentsMargins() in the Qt examples. * Made the IPAddress single-argument-String constructor explicit. * Fixed a bug in the iOS implementation of DetectNetworkConfigChangesSession that could cause crashes during shutdown. * Fixed a bug in Hashtable::HasKeysInCommonWith() that would cause it to infinitely recurse if the two tables were the same size. * Fixed a bug in Message::ReplaceFlat() that would cause it to add incorrect data to the Message if the field didn't already exist. 8.46 - Released 1/8/2022 - Added HashCode() methods to the ByteBuffer, Queue, Hashtable, FilePathInfo, muscle_thread_id, and PointerAndBool classes. - Added a CalculateHashCode() function that takes an array as an argument and returns a hash code for the entire array. - Rewrote the deadlock-finder's lock-logging code to use a finite amount of RAM rather than an ever-growing amount. - Added PrintMutexLockingReport() to print out out the current state of the -DMUSCLE_ENABLE_DEADLOCK_FINDER debug-info without having to exit the process. - Added ToHexString() and ToAnnotatedHexString() methods to the ByteBuffer class. - Added a suppressLeadingZeroes argument to BitChord::ToHexString() - Added a MaxCacheableTableSize template-argument to the ImmutableHashtable classes. - Added logic to the ImmutableHashtable class to mutate a table in some circumstances (when nobody will notice) to avoid creating a lot of superfluous interim tables. - Added a Hashtable::HasKeysInCommonWith() convenience method. - Added a DropAllCacheEntriesContainingAnyOfTheseKeys() method to the ImmutableHashtablePool class, for better efficiency. - Hashtable::Remove() and Hashtable::Intersect() methods are now templated so their argument can be a Hashtable of a different type (as long as its KeyType is the same) o CalculateHashCode(const Type &) now calls HashCode() on the argument if possible, or uses a PODHashFunctor otherwise. o Downgraded cmake_minimum_required in the CMakeList.txt files to 2.8.12, in order to regain compatibility with older build environments o Replaced instances of MutexGuard objects manually being placed on the stack with DECLARE_MUTEXGUARD() macro invocations, for better code-safety and deadlock-finder compatibility. o MutexGuard now triggers a crash if its call to Lock() or Unlock() its Mutex fails. o Removed MutexGuard::IsMutexLocked() since it is no longer possible for that method to return false. o Added a Mutex::GetNativeMutexImplementation() method for accessing the Mutex class's back-end directly, if necessary. o Removed deadlockfinder.cpp because its functionality is built in to the core MUSCLE library now. o Refactored various status_t returning code to use MRETURN_ON_ERROR macro instead of manual status-variable management, for better readability. o Moved various trivial functions out of MiscUtilityFunctions.cpp and into SetupSystem.cpp, to reduce linking dependencies. * Refactored the Mutex class so that the code associated with the -DMUSCLE_ENABLE_DEADLOCK_FINDER deadlock-finding feature integrates better with TryLock() and the MutexGuard class. * Updated DECLARE_MUTEXGUARD to explicitly specify the muscle namespace, so it can be used from other namespaces also. * AutoChooseHashFunctor's explicit instantiations neglected to declare the Type field as public. Fixed. 8.45 - Released 12/21/2021 - Added a GetSessionsByIDNumber() method to the ReflectServer and ServerComponent clases, for session-lookup with uint32 key. o DataNodeSubscribersTable now uses uint32 keys instead of String keys, for better efficiency. o Inlined some trivial functions in the ReflectServer class. o Changed the Python 2 code to use xrange() instead of range(). * Fixed the Windows implementation of the Directory class to work correctly in 64-bit builds. * Fixed various MSVC2022 warnings in the muscle-by-example code. * Fixed several race conditions reported by ThreadSanitizer. * DummyRef and DummyConstRef constructors now inherent the IsRefCounting() parameter of their Ref argument verbatim, to avoid bugs introduced by implicit-constructor insertion. * Updated the PointerAndBool classes to hold their internal state as a (uintptr) instead of a (T*), to avoid any potential undefined behavior that might arise from holding a non-aligned object-pointer. 8.44 - Released 11/17/2021 - Added new methods ObjectPool::PerformSanityCheck() and AbstractObjectRecycler::GlobalPerformSanityCheck() to make it easier to detect memory-corruption issues in the future. - Improved the robustness of the SimulatedMulticastDataIO's distributed-ping algorithm. - Added a templated Arg(const T &) method to the String class so that you can pass a reference to any object with a ToString() method and it will call ToString() on the object implicitly. - Added templated + and += operators for the String class, so you can append an object with a ToString() method without having to explicitly call ToString() on it. * Merged in Kreeblah's FreeBSD 13.0 compatibility fixes. * Fixed a bug in Queue::Clear() that allowed the Queue to remain un-normalized in some cases after Clear() returned. This bug could in turn cause Message::Unflatten() to corrupt memory. * Fixed an MSVC warning in GlobalMemoryAllocator.h about strdup() 8.43 - Released 10/25/2021 - Added BitChord::GetNumBitsSet() method. - Added a Message::SortDataInField() method. - Added HasBufferedIncomingText() method to PlainTextMessageIOGateway - Added a Hashtable::SwapWithTable() method for swapping a key/value pair. - Added a Message::SwapName() method for swapping a named field. - The CMakeLists.txt file now supports a WITH_SSL=ON option to compile the muscle library with OpenSSL support enabled. - Added a second constructor to FileDataIO to allow the call to fopen() to be deferred until the first time the calling code tries to use the FileDataIO's I/O methods. - Added a muscleStrdup() function, for convenience. - Added an optional (escapeChar) argument to the StringTokenizer class constructors, to allow specifying an escape-character that can be inserted before separator-chars that are intended to be interpreted as literals. - StringTokenizer class now uses a bit-chord lookup rather than strchr() when determining if a character is a separator-char. - Added String::WithCharsEscaped() to support appropriate backslash-insertions before specified "special" chars. - Added Split() and Join() convenience-methods to the StringTokenizer class, for easy conversion between a String and a Queue of sub-strings. o Removed the GetHardSeparatorChars() and GetSoftSeparatorChars() methods from the StringTokenizer class. o Updated the cmake_minimum_required in CMakeLists.txt to 3.0 to avoid deprecation warnings. o Moved PrintSessionsInfo() and PrintFactoriesInfo() up out of StorageReflectSession and into AbstractReflectSession. o Changed the ComputerIsAboutToSleep() and ComputerJustWokeUp() methods of the INetworkConfigChangesTarget interface to be implemented as no-ops methods instead of pure-virtual. * PlainTextMessageIOGateway::DoInput() now flushes its input buffer when it's in flush-partial-incoming-lines mode, even when it didn't actually read any more bytes. * Fixed a bug in MiniPacketTunnelIOGateway::DoOutput() that could cause it a buffer overrun when under load. * Updates testpackettunnel.cpp to be able to test either PacketTunnelIOGateway or MiniPacketTunnelIOGateway * Fixed the #include-guards and copyright-comments of several header files that didn't have them included correctly. * The StringTokenizer copy-constructor now handles copying from (StringTokenizers using user-provided memory) more elegantly. 8.42 - Released 9/18/2021 - Added a DummyConstSocketRef class, for consistency with the existing DummyConstXXXRef naming conventions - Modified MessageTransceiverThread::AddNewSession() and MessageTransceiverThread::AddNewConnectSession() to take an AbstractReflectSessionRef argument instead of a ThreadWorkerSessionRef, to allow the addition of non-ThreadWorkerSession session objects to the internal ReflectServer when necessary. - Modified MessageTransceiverThread::PutAcceptFactory() to take a ReflectSessionFactoryRef argument instead of a ThreadWorkerSessionFactoryRef argument. - Added a muscleStrError(int) function to MuscleSupport.h, just to avoid warning messages under MSVC. o Made the one-argument ConstSocketRef constructor explicit. o Removed the ConstSocketRef(const Socket *, bool) constructor; use the new DummyConstSocketRef class intead. * muscleSnprintf now calls _vsnprintf() (with appropriate wrapper-logic to ensure NUL-termination in all cases) when compiled on MSVC older than MSVC2015; in all other environments it is now a simple synonym for snprintf(). * muscleStrncpy() now calls through to strncpy() in all cases, but also ensures that the last byte in the destination-buffer is set to NUL. * Changed B_ERRNUM to be an inline-function instead of a #define, to avoid double-evaluation of its argument. 8.41 - Released 9/1/2021 - Added an NWPathMonitor-based implementation to the DetectNetworkConfigChangesSession class so that changes to the local network devices can be detected properly under iOS. - Added a PointerAndBools class for PointerAndBool.h, for extremely frugal programmers who want to smuggle two booleans into their pointer-fields. o Removed the "virtual" tag from the QueueStackGuard class constructor since it isn't necessary. o Changed ReflectServer's _lameDuckSessions to be a Hashtable instead of a Queue, for better consistency with _sessions. * Fixed a bug that could cause ReflectServer to occasionally generate a spurious resource-leak warning for a lame-duck session, just before the session was disposed of. * CMakeLists.txt now sets CMAKE_OBJECT_PATH_MAX to 500 to work around path-length restrictions under Windows. 8.40 - Released 7/15/2021 - Added a Windows-only convenience-constructor to the Socket class that takes a SOCKET instead of an int, for easier capture of Windows socket-descriptors into Socket objects. - Added Windows-only convenience-version of the GetConstSocketRefFromPool() function that takes a SOCKET instead of an int, for easier capture of Windows socket-descriptors into ref-counted Socket objects. - Added ICallbackMechanism, ICallbackSubscriber, and SocketCallbackMechanism classes to support OS-neutral inter-thread event dispatching. - Added Win32CallbackMechanism for integration into Win32 event loops. - Added SDLCallbackMechanism for integration into SDL event loops. - Added QSocketCallbackMechanism and QPostEventCallbackMechanism for integration into Qt event loops. - Thread class now inherits from ICallbackSubscriber and its constructor optionally takes a pointer to an ICallbackMechanism that can be used to automatically handle Messages sent back to the owning thread by the Thread's internal thread. o Moved platform-specific code into a "platform" subdirectory. o Moved (non-C++) language-specific code into a "lang" subdirectory. o Changed MessageTransceiverThread::SendMessageToSessions() (and friends) to pass strings as (const String &) rather than as (const char *). o Removed Win32MessageTransceiverThread and SDLMessageTransceiverThread classes. o Removed the AcceptSocketsThread and QAcceptSocketsThread classes. o Removed support for AtheOS, BeOS, and Haiku (since AFAICT nobody was using it, and because previous changes to the status_t type had rendered the codebase unbuildable on those platforms anyway) o Renamed portablereflectclient.cpp to singlethreadedreflectclient.cpp o Removed testreflectclient.cpp and replaced it with multithreadedreflectclient.cpp o Moved the Python2-specific .py files into a python2 folder, for clarity. o Removed win32client.cpp from the test folder (see multithreadedreflectclient.cpp instead) o Removed the LockSignalling() and UnlockSignalling() methods from the Thread class as they aren't useful any longer. * Fixed an error with the usage of the fErrorChar and ErrorChar fields in the Windows implementation of the RS232DataIO class constructor. (Thanks to Mika Lindqvist for providing this fix) * Some of the "time since previous packet" metadata output in hexterm's stdout output was incorrect. Fix. 8.30 - Released 6/2/2021 - Added DummyRef and DummyConstRef classes to util/RefCount.h, to support reader-friendly declarations of references to stack-based objects. - Added the ImmutableHashtable and ImmutableHashtablePool classes to support memory-efficient instancing of redundant Hashtables across multiple call sites. - Added a ToString() method to the BitChord class for easier debugging. - Added a WITH_THREADS CMake argument, to disable linking to threads library. - Added a WITH_SANITIZE CMake argument, for building MUSCLE with some of clang's sanitization-checkers enabled. - Added WouldBeEqualToAfterPut(), WouldBeEqualToAfterRemove(), WouldBeEqualToAfterPutOrRemove(), AreKeysAndValuesASubsetOf(), and AreKeysAndValuesASupersetOf() methods to the Hashtable class. - Added an optional (considerOrdering) argument to the Hashtable::AreKeysEqual() and Hashtable::AreKeys*Of() methods. - Added a HashCode() method to the Void class so that a Hashtable can be used in conjunction with an ImmutableHashtablePool. - Added a QueueStackGuard convenience class to Queue.h - Updated the ObjectCounter class and PrintCountedObjectInfo() to also report sizeof(ObjectType) for each counted-object-type. o Modified the ObjectCounterBase class so it no longer contains any virtual methods. o Made one-argument constructors for several QueryFilter subclasses explicit. o Made the explicit-two-argument constructors for Ref and ConstRef private; use the new DummyRef and DummyConstRef classes instead of calling them. o Rewrote the DataNodeSubscribersTable code to use the new ImmutableHashtablePool class instead of its own private logic. o Hexterm now prints out the number of reads it has done so far. o PrintCountedObjectInfo() now sorts its output by size (biggest RAM hogs first) and prints total-objects-counted and total-memory-counted stats. * Applied various fixes based on warnings supplied by cppcheck. * Modified TCPSocketDataIO::FlushOutput() to no longer call SetSocketCorkAlgorithmEnabled() when compiled under MacOS/X, because MacOS/X's implementation of TCP_NOPUSH is problematic. * StringMatcher::SetPattern() wasn't escaping + characters when converting simple-wildcard-strings to regex-strings. Fixed. * Fixed a bug where Hashtable::IsEqualTo() wouldn't compare values when the (considerOrdering) value was passed in as true. 8.20 - Released 4/26/2021 - Added ARRAYROWS and ARRAYCOLS functions to MuscleSupport.h (These are similar to the existing ARRAYITEMS except they return the first and second dimensional-extents of a 2D array) - Added AreKeysASupersetOf() and AreKeysASubsetOf() convenience methods to the Hashtable class. - Added an optional (fromIndex) argument to String::Replace() and String::GetNumInstancesOf(). - CMake now compiles the executables in the tests folder also. - CMake now compiles the executables in the html/muscle-by-example/examples/* sub-folders also. - CMake now includes zip/unzip functions from zlib/zlib/contrib/minizip in the generated muscle.lib. - Added support for the -DMUSCLE_ENABLE_LOCKING_VIOLATIONS_CHECKER compile-time flag and the associated functionality in the Mutex class (see BUILDOPTIONS.txt for details) - Added a NeuterMutex() method to the ObjectPool class. o Changed ARRAYITEMS to return uint32 instead of unsigned int. o Changed ChildProcessDataIO::WaitForChildProcessToExit() to return a status_t rather than a bool. o Removed obsolete Win95/Win98 support code from RS232DataIO.cpp. o Removed all MSVC project files from the distribution (use cmake to generate .vcproj files on-demand instead) o Removed Borland Makefiles as obsolete. o Removed dev-C++ Makefiles as obsolete. o Added explicit assignment-operators to several classes so that g++ 9.3.0 wouldn't warn about deprecated implicit behavior. * Fixed several const-correctness problems in the minizip code. * Updated chatclient, testudp, and portableplaintextclient tests to use a StdinDataIO rather than selecting on STDIN_FILENO, so that they can work as expected under Windows. * Fixed the CMakeList.txt to link to pthreads and util libraries when appropriate (before it would only do so if Qt was installed) * Fixed a potential string-terminator bug in TarFileWriter::WriteFileHeader(). * Fixed various minor compiler-warnings. 8.10 - Released 4/5/2021 - Added ByteBufferPacketDataIO class to the dataio folder. - Win32 implementation of ChildProcessDataIO now uses a variable-duration polling algorithm to improve data-transfer rate from child's stdout to parent process. - Added a Prefill() method to the ObjectPool class. - Added a new flag SETDATANODE_FLAG_ENABLESUPERCEDE to the SetDataNodeFlags enum. PR_COMMAND_SETDATA Message specifying this flag will try to remove any previously-enqueued-but-still-pending updates regarding the DataNodes they modify, so as not to build up a FIFO backlog of update-Messages when the server is under a heavy update-load. - PR_COMMAND_SETDATA parser now accepts PR_NAME_FLAGS field as either a SetDataNodeFlags or a uint32, for convenience when client isn't C++-based. - Added UpdateSubscriptionMessage(), PruneSubscriptionMessage(), and UpdateSubscriptionIndexMessage() hook-methods to the StorageReflectSession class. - Added GetStringReference() convenience-method to the Message class. - Added MLOG_ON_ERROR, MPRINT_ON_ERROR, MLOG_AND_RETURN_ON_ERROR, and MPRINT_AND_RETURN_ON_ERROR macros for convenient error-logging. - Added a MiniPacketTunnelIOGateway class, for maximally efficient packing of multiple smaller-than-MTU Messages together into UDP packets. - The ZLibCodec class now inherits from RefCountable. - Added SetPacketRemoteLocationTaggingEnabled() and GetPacketRemoteLocationTaggingEnabled() methods to the AbstractMessageIOGateway class. - Added a ProxyIOGateway class that centralizes some common code used by both the PacketTunnelIOGateway and the MiniPacketTunnelIOGateway (and potentially other "decorator" style gateways in the future) o Moved the declaration of the SetDataNodeFlags BitChord type from StorageReflectSession.h to StorageReflectConstants.h. o Modified the NotifySubscribersThatNodeChanged() and NodeChanged() methods in StorageReflectSession. to accept a NodeChangeFlags argument instead of a boolean. o Modified the SetData() method in DataNode to accept a SetDataFlags argument instead of a boolean. o Simplified error-handling in various locations by using MRETURN_ON_ERROR instead of explicit if/returns. o Moved the AbstractGatewayMessageReceiver and QueueGatewayMessageReceiver classes out of AbstractMessageIOGateway.h and into their own file AbstractGatewayMessageReceiver.h o Updated the README.html to include descriptions of recently-added classes. o Updated the muscle.dox file to match the latest Doxygen codebase. * Fixed #include in Win32FileHandleDataIO.h * Fixed a bug in IPAddress::SetIPv4AddressFromUint32() that was causing it to set the interface-index of an IPv4 address to 0 instead of to MUSCLE_NO_LIMIT/invalid. * Fixed a potential buffer-overrun in StorageReflectSession::NodeIndexChanged(). * PacketDataIO::Write() was mis-named WriteTo(). Fixed. * Fixed a bug in qt_advanced_example.cpp that caused the InternalThreadSessions display to be rendered incorrectly. 8.00 - Released 3/8/2021 - Added TemplatedFlatten(), TemplatedUnflatten(), TemplatedFlattenedSize(), and CreateMessageTemplate() methods to the Message class, to allow encoding of a Message's payload-data separately from its metadata. - Added a TemplatingMessageIOGateway class that takes advantage of Message's new templated-flattening functionality to reduce network bandwidth. - Added GetAndMoveToFront() and GetAndMoveToBack() convenience-methods to the Hashtable class. - Added protected GetSendCodec() and GetReceiveCodec() methods to the MessageIOGateway class, so subclasses can access them. - Added a DMUSCLE_USE_TEMPLATING_MESSAGE_IO_GATEWAY_BY_DEFAULT compile-time flag, to make it easier to exercise the TemplatedMessageIOGateway class. Defining this flag causes the AbstractMessageIOGateway class to use a TemplatedMessageIOGateway by default. - Added a (maxRecursions) argument to the SortFieldNames() method of the Message class. - Added a .And() method to the status_t class for easier ordered-chaining of multiple status_t-returning calls (available under C++17 and later only) - Added a MUSCLE_USE_CPLUSPLUS17 define that is automatically set when compiling with C++17 or later. - Added a MRETURN_ON_ERROR macro to facility returning of status_t error-codes from function calls. - Added a MRETURN_OOM_ON_NULL(ptr) macro that will invoke MRETURN_OUT_OF_MEMORY if the passed-in pointer is NULL. o Added template-testing code to testmessage.cpp o Replaced explicit comparisons to B_NO_ERROR with calls to .IsOK() and .IsError() o Renamed WARN_OUT_OF_MEMORY macro to MWARN_OUT_OF_MEMORY to reduce the chance of macro-namespace collisions. o Renamed RETURN_OUT_OF_MEMORY macro to MRETURN_OUT_OF_MEMORY to reduce the chance of macro-namespace collisions. o Renamed DECLARE_ANONYMOUS_STACK_OBJECT macro to MDECLARE_ANONYMOUS_STACK_OBJECT to reduce the chance of macro-namespace collisions. o Renamed DECLARE_DEBUGTIMER to MDECLARE_DEBUGTIMER to reduce the chance of macro-namespace collisions. * Fixed a bug where calling Message::AddData() with a NULL data-pointer could cause a crash. * Fixed a potential crash-on-exit bug in the StorageReflectSession class's Cleanup method. * Fixed a bug in the pthreads implementation of Mutex::TryLock() (it was calling through to pthread_mutex_lock() rather than pthread_mutex_trylock()) 7.71 - Released 2/14/2021 - Added copy-constructor and assignment-operator to the StringTokenizer class. - Added an IndexOfName() method to the Message class. o Updated the muscle.dox file to work with Doxygen v1.9.2. o Fixed some ClangSA warnings o Modified Hashtable::PutOrRemove() to return a status_t instead of a pointer-to-value. o StringTokenizer constructor now takes separate arguments for "hard" and "soft" separator-chars (with multiple contiguous "hard" separator-chars returning empty strings when tokenized, while contiguous "soft" separator-chars will be handled as a single separator) o Removed svncopy.cpp from the tests subfolder. o Added teststringtokenizer.cpp to the tests subfolder. * SetSocketMulticastToSelf() was broken under MacOS/X; fixed. * The calls to ReadFromNetworkArray() inside NetworkUtilityFunctions.cpp no longer pass zero as an interface index, to avoid an unnecessary @0 suffix in IPv6 address strings. * Modified DetectNetworkConfigChangesSession.cpp to again compile when _WIN32_WINNT is set to 0x0501 (aka WinXP) * Fixed a bug in the Win32 implementation of Thread::SetThreadPriority() that would cause it to always return B_UNIMPLEMENTED. 7.70 - Released 1/8/2021 - The subscribed-sessions tables used by DataNode objects are now immutable and shared across multiple DataNodes when appropriate, reducing the server's RAM usage. - Added IsInterfaceIndexValid(), UnsetInterfaceIndex(), SetInterfaceIndexFrom(), and WithoutInterfaceIndex() methods to the IPAddress class. - Added AddTailIfNotAlreadyPresent() and AddHeadIfNotAlreadyPresent() convenience methods to the Queue class. - Added a (defaultInterfaceIndex) value to IPAddress::GetInterfaceIndex() to specify what to return if the current interface index value isn't valid. Defaults to zero. - Added IPAddress::IsIPv6NodeLocalMulticast() and IPAddress::IsIPv6LinkLocalMulticast() convenience methods. - Added == and != operators to the NetworkInterfaceInfo class. o Modified the DataNode::GetSubscribers() method to return a (const Hashtable &) rather than a (HashtableIterator) o Split Queue::RemoveDuplicateItems(bool) into Queue::RemoveDuplicateItems() and Queue:RemoveSortedDuplicateItems(). o Revised the way interface-index values are handled in the IPAddress class. Now unset/invalid interface-indices are represented internally via a guard value (MUSCLE_NO_LIMIT) rather than 0. o IPAddress::ToString()'s (printIPv4AddressesInIPv4Style) argument now defaults to true instead of false. o Modified muscleArrayIndexIsValid() to reference (theArray) via a dummy (theArray==theArray) test rather than a (theArray!=NULL) test, as the latter test can generate a warning at compile time. 7.62 - Released 11/20/2020 - Added a ToBinaryString() convenience-method to the BitChord class. - Updated TarFileWriter so that it can now write using non-seekable DataIO objects as well as SeekableDataIO objects (although with non-seekable you have to explicitly specify the file sizes up-front) - Updated the captive zlib implementation to the latest (v1.2.11) - Added CallFlattenHeaderAndMessage() and CallUnflattenHeaderAndMessage() convenience-methods to the MessageIOGateway class. - Added a GZDataIO class to the zlib folder, as quick way to wrap the gzread()/gzwrite() API inside a DataIO interface. o Modified CMakeList.txt to avoid policy warnings under Windows. * Fixed pointer-casting in Windows call to SetWindowLongPtr() * Fixed a bug where String::WithoutSuffix() and String::WithoutPrefix() would spin the CPU if they were passed an empty String as an argument. Now these methods immediately return (*this) in that case, instead. 7.61 Released 8/5/2020 - Removed MUSCLE's requirement that indexed-child-nodes' node-names must start with the capital letter I. Now any name is acceptable for use as an indexed-child-node. - Added a new Arg(double, uint32, uint32) overload to the String class, which can yield better floating-point-to-String formatting than the standard printf() specifiers provide. - muscleMin(), muscleMax(), and various other inline functions in MuscleSupport.h are now tagged as MUSCLE_CONSTEXPR so that they can be evaluated at compile-time when possible. o muscleArrayIndexIsValid now returns false if the passed-in array-pointer is NULL. * Fixed a warning in the CMakeLists.txt that would occur on build systems that don't have Qt installed. 7.60 Released 6/25/2020 - Added a "daemonsitter" program to the tests folder, to demonstrate how to use MUSCLE to babysit a litter of child processes. - Added a ChildCountQueryFilter class, for constructing QueryFilters that take the number of child nodes of a DataNode into account when deciding on a match. - Merged in Richard Spindler's addition of CMakeList.txt files so that the Qt example programs are now built via cmake when possible, and also so that MUSCLE's Qt support code is built into a separate qtsupport library. - Added an optional (prepend) argument to the AssembleBatchMessage() utility function. - SimulatedMulticastDataIO now tries to send a test UDP packet on its UDP socket before committing to use it. - Updated server/Makefile to conditionally build for Catalyst based on presence of ENABLECATALYST env-var. - Added a testserverthread.cpp program to the tests folder to test/demonstrate launching a child thread that runs its own ReflectServer event loop, and how the main thread can send Messages to it - Added a GetEffectiveParameters() convenience method to the StorageReflectSession class. o Modified StorageReflectSession::SetDataNode(), RestoreNodeTreeFromMessage(), and CloneDataNodeSubree() to take a bit-chord of SETDATANODE_FLAG_* bits rather than an error-prone list of boolean arguments. o Added a dummy symbol to GlobalMemoryAllocator.cpp to avoid a "GlobalMemoryAllocator.o has no symbols" warning o Modified CMakeLists.txt to use WITH_MUSCLED option instead of BUILD_MUSCLED environment variable. o Changed MessageIOGateway's MessageFlattenedCallback's return type from void to status_t, so that the callback can affect whether the Message goes out or not. 7.55 Released 5/7/2020 - Rewrote DetectNetworkConfigChangesSession's Windows and Mac implementation to use a single thread for all DetectNetworkConfigChangesSessions in the process, rather than one thread per DetectNetworkConfigChangesSession. - Added a Python implementation of the BitChord class to python/bit_chord.py - Added PutFlat() and GetFlat() convenience methods to the Python Message class in message.py - Added SegmentedStringMatcher to the libmuscle.a build. - Added some experimental support for building libmuscle.a as a Catalyst-compatible library (see server/Makefile) - Added GetAndClearBit(), GetAndSetBit() and GetAndToggleBit() convenience methods to the BitChord class. - Added a SetErrno(int) function to MuscleSupport.h, to complement the existing GetErrno() function. - Added muscleproxy.cpp to the tests sub-folder, as simple demonstration of how to implement a proxy using MUSCLE. - Added a MoveIndexEntries() convenience method to the StorageReflectSession class. - Added CAddArchiveMessage() and CPrependArchiveMessage() convenience methods to the Message class. - Added an optional (maxSegments) argument to the SetPattern() method of the SegmentedStringMatcher class. - Added a "Clone Window" button to the qt_muscled_browser GUI. - Made qt_muscled_browser's stdout output prettier. o Modified SendDataUDP() so that when it returns, errno is still set to the state that the sendto() call set it to. o Moved the NODE_DEPTH_* enum out of the StorageReflectSession class and up into muscle-namespace scope, so that it can be referenced by non-StorageReflectSession code. * Added a work-around to SimulatedMulticastDataIO for the occasional MacOS/X bug that causes SendDataUDP() to always return ENOBUFS on a Wi-Fi device's socket. This won't fix the underlying problem in MacOS/X, but it will at least keep SimulatedMulticastDataIO from spinning a core at 100% when the fault occurs. 7.54 Released 3/20/2020 - Added a B_ERRNUM(e) macro that works similarly to B_ERRNO, except it calls strerror() with the passed-in integer value rather than calling strerror(errno). - Added a TryLock() method to the Mutex class. - Added a WithReplacements() method to the String class that takes a (const Hashtable &) argument, for doing multiple simultaneous search-and-replace operations at one time. * Fixed the handling of RTM_NEWADDR and RTM_DELADDR messages in the Linux implementation of DetectNetworkConfigChangesSession. * Tweaked the Windows #ifdef's in ChildProcessDataIO.cpp per Mika * Return values of pthreads functions weren't being used correctly to set status_t results on error. Fixed. 7.53 Released 2/13/2020 - Added a new FlushOutput() virtual method to the AbstractMessageIOGateway class, in case a subclass needs to hook into the gateway's flush-output functionality. - Added a ParseArgs(const Queue &, Message &, bool) convenience-method to MiscUtilityFunctions.{cpp,h}. - hexterm now reports more details about certain network errors. - Updated the MacOSX/iOS implementation of GetNetworkInterfaceInfos() to call ioctl(SIOCGIFFUNCTIONALTYPE) to disambiguate the device-type of a network-interface device. o Added the MUSCLE_CONSTEXPR tag to the TimeUnitConversionFunctions so that they can be evaluated at compile time when possible. o Modified SharedFilterSessionFactory.cpp to treat an all-zeros shared memory region the same as a non-existent one (so that we no longer have to delete the memory region just to return the filter's behavior to its default state) o Moved the FlushOutput() calls for the gateway classes up into AbstractMessageIOGateway::DoOutput() so that it only needs to be implemented in one place rather than separately in each subclass. o Modified the gateway classes to fail gracefully if GetDataIO() returns a NULL reference, instead of dereferencing a NULL pointer. o Updated the friend-template workaround in Hashtable.h to apply to all versions of GCC, to avoid having to update the code every time a new version of GCC comes out with the bug still unfixed. 7.52 Released 11/28/2019 - Enabled bitcode-generation for iOS in the CMakeLists.txt file. - Added SetSocketCorkAlgorithmEnabled() and GetSocketCorkAlgorithmEnabled() functions to the NetworkUtilityFunctions API (currently implemented for Linux, BSD, and MacOS/X) - TCPSocketDataIO::FlushOutput() now also calls also the new SetSocketCorkAlgorithmEnabled() function for better efficiency. o Moved inline code out of TCPSocketDataIO.h, UDPSocketDataIO.h, ByteBufferDataIO.h, and FileDataIO.h and into corresponding .cpp files. o Split hexterm's "file=blah" argument into "rfile=blah" and "wfile=blah" to allow hexterm to also write hex bytes into a file. o Replaced explicit type-comparisons in message.py with calls to isinstance(). o message.py now tests sys.byteorder to determine the native CPU's endianness * PlainTextMessageIOGateway wasn't calling FlushOutput() on its DataIO object at the appropriate times. Fixed. * Removed some obsolete backwards-compatibility-with-early-Python-2.x code from the python3/message.py class. * Refined the exception-handling in message_transceiver_thread.py 7.51 Released 10/22/2019 - Added a MUSCLE_ENABLE_AUTHORIZATION_EXECUTE_WITH_PRIVILEGES compile-time flag and a SetRequestRootAccessForChildProcessEnabled() method to the ChildProcessDataIO class that will be available only on MacOS/X and only if the compile-time flag was specified when compiling MUSCLE. The new method tells the ChildProcessDataIO class to launch the child process as a privileged/root-level process (and causes the OS to prompt for the user's password before allowing that) - Moved the time-unit-conversion helper-functions into their own separate header file (util/TimeUnitConversions.h), and implemented the full matrix of possible unit-conversions within the set of supported time-units. 7.50 Released 9/25/2019 - Merged in some iOS-compatibility patches supplied by Arno Gramatke. The CMakeLists.txt now does the right thing for iOS, and several non-iOS-supported classes (i.e. DetectNetworkConfigChangesSession and RS232DataIO) now compile under iOS as dummy/no-op classes, rather than breaking the build. - Added a B_ERRNO macro which is similar to B_ERROR, except it automatically references the current errno-string, as returned by strerror(errno). - Added various status_t error-constants for "common" error types, such as B_BAD_ARGUMENT, B_DATA_NOT_FOUND, B_OUT_OF_MEMORY, B_FILE_NOT_FOUND, etc. See support/MuscleSupport.h for the full list. - Added IsOK(status_t &) and IsError(status_t &) methods to the status_t class, to support short-circuit logic chains that return an error-description string (see test/teststatus.cpp for examples) - Added a RETURN_OUT_OF_MEMORY macro to formalize the common "WARN_OUT_OF_MEMORY; return B_OUT_OF_MEMORY;" couplet. - Merged in Mika Lindqvist's patch for VS2019 and ARM64. o Instead of an enum/int, the status_t class now holds a (const char *) containing a human-readable description of the error that occurred (or a NULL pointer to indicate that the operation succeeded). o B_ERROR now optionally takes a (const char *) argument specifying a human-readable error-string describing the error that occurred. o Updated the codebase to return more specific status_t error strings when possible (instead of only B_ERROR). o Updates the codebase so that LogTime() calls reporting an error now include the state-string of the relevant status_t variable, when applicable. o The Mutex, SharedMemory, TarFileWriter, and ZLibCodec classes all now now inherit from NotCopyable. * Updated the friend-template work-around in Hashtable.h to include g++ 8.3.x * Fixed an output-formatting bug in test/readmessages.cpp * Fixed a bug in test/readmessage.cpp that could cause readmessage to crash when reading an invalid file. 7.41 Released 8/8/2019 - Added a SwapContents() method to the StringMatcher class, and also a move-constructor and a move-assignment-operator. - The CMakeLists.txt file can now take an optional -DBUILD_MUSCLED=OFF argument, for use-cases where the user wants only muscle.lib to be built and not muscled. - The Cloneable interface class now includes logic to verify that the object returned by Clone() is of the correct subclass, and will trigger an assertion-failure if it isn't. - Added a test/testclone unit-test program to test Cloneable. o Moved AbstractReflectSession::GetTypeName() up into the ServerComponent superclass, and gave it a default implementation (based on RTTI) so that it no longer needs to be implemented manually by every subclass. 7.40 Released 7/23/2019 - Added an AndQueryFilter class, for better ease-of-use. - Added an OrQueryFilter class, for better ease-of-use. - Added a NandQueryFilter class, for better ease-of-use. - Added a NorQueryFilter class, for better ease-of-use. - Added IsKeyLocatedInThisContainer() and IsValueLocatedInThisContainer() methods to the Hashtable class (to match the IsItemLocatedInThisContainer() method already present in the Queue class) o Renamed the existing AndOrQueryFilter class to MinimumThresholdQueryFilter. This class now serves as the superclass of the AndQueryFilter and OrQueryFilter classes. o Renamed the NandNotQueryFilter class to MaximumThresholdQueryFilter. This class now serves as the superclass of the NandQueryFilter and NorQueryFilter classes. o Tweaked some #ifdefs so that MUSCLE code can be compiled to WebAssembly using Emscripten. o Added support for a -DMUSCLE_USE_DUMMY_DETECT_NETWORK_CONFIG_CHANGES_SESSION build-flag, for easier test-building on systems that aren't currently supported by the DetectNetworkConfigChangesSession * Rewrote testqueryfilter.cpp to unit-test the new classes. * Fixed some compiler-warnings in the included Qt-examples. * Various style tweakages in response to suggestions generated by GitHub CodeFactor * Added the 'class' keyword to a couple of friend-declarations in SSLSocketDataIO.h, since pre-C++11 compilers require it. * Fixed a use-after-free bug that could occur when the Hashtable class's Put() methods needed to allocate a larger internal array to hold the new item, AND the passed-in value-argument was a reference to an object that was located within the Hashtable's old data-array. * Fixed a bug similar to the above in the Queue class's AddHead*() and AddTail*() methods. 7.31 Released 7/11/2019 - Updated muscled.cpp and portablereflectclient.cpp so that either one can specify public or private keys to load. - Added tests/testhashcodes.cpp, to check the consistency of CalculateHashCode() and CalculateHashCode64() across CPU architectures. o ChildProcessDataIO::ChildProcessReadyToRun() now returns B_NO_ERROR if the child process should run, or B_ERROR if the child process should be aborted. o Modified the Hashtable-templatized-friend workaround to be active on g++ up to v8.2.0. * Fixed a bug that could cause the Message class's equality operator to incorrectly return true in the case where both Message objects are semantically the same, but are pointing to different (yet identical) binary data-buffers. * Fixed some errors and omissions in the README.html file. 7.30 Released 6/7/2019 - Added a GetErrno() function to MuscleSupport.h, as a portable front-end to either errno or WSAGetLastError(), depending on OS. - The tests/readmessage.cpp program now inflates zlib-compressed files, and takes a new optional "sizes" keyword, which, if specified, will cause the program to print a report of how many bytes each sub-Message in the file takes up, sorted by increasing size. - Added a SetPreSharedKeyLoginInfo() method to the SSLSocketDataIO class so that it can now support PSK-based authentication. - Added GetPreSharedKeyUserName() and GetPreSharedKeyPassword() methods to the SSLSocketDataIO class. - Added a SetSSLPreSharedKeyLoginInfo() method (and corresponding GetSSLPreSharedUserName() and GetSSLPreSharedPassword() methods) to the ReflectServer class. - Added a SetSSLPreSharedKeyLoginInfo() method to the MessageTransceiverThread class. - Added a SetPrivateKey(const ConstMessageRef &) convenience method to the SSLSocketDataIO class. - Modified the ReflectServer class so that any combination of public, private, and pre-shared keys can be applied to newly created sessions. o Hashtable.h was using some C++11-specific syntax that would cause a warning to be generated when compiling in C++03 mode. Fixed. o Added an "if(TARGET muscle) return()" idempotency test to the CMakeLists.txt file, to avoid potential cmake errors. o Dropped support for old (pre-1.1.x) versions of OpenSSL from the SSLSocketDataIO class. * The CMakeLists.txt now links in the IOKit framework under MacOS/X. 7.21 Released 5/7/2019 - ChildProcessDataIO::LaunchChildProcess() and friends now take an optional Hashtable that, if specified, will be passed to the child process as environment-variables. o Reduced sizeof(Hashtable) by 8 bytes, from 64 to 56. o Queues of very small Item-types (e.g. 1 or 2 bytes per Item) now automatically get larger ACTUAL_SMALL_QUEUE_SIZE values, to take advantage of space that would otherwise be wasted as padding anyway. o Added some indentation-style fixes for member-initializers 7.20 Released 4/23/2019 - Added new convenience methods to the Hashtable class: PutAtFront(), PutAtBack(), PutBefore(), PutBehind(), and PutAtPosition(). (These are variations of Put() that allow the caller to simultaneously specify the desired position of the object in the table's iteration-sequence) - Added a ParseNumericSuffix() method to the String class. - The StringTokenizer class no longer performs a heap allocation when tokenizing short strings. - Added ReadFlat(), WriteFlat(), and AppendFlat() methods to the ByteBuffer class. - Added a Reposition(const KeyType &) method to the OrderedKeysHashtable class. o Added const-qualifiers to more local variables where appropriate. o Refactored the Hashtable class's internal sorting implementation to reduce the amount of redundant code. o Moved all of the auto-sort functionality out of the HashtableBase class and into an OrderedHashtable subclass that OrderedKeysHashtable and OrderedValuesHashtable now derive from. o Hashtable::SwapContents() no longer swaps the values of the auto-sort-enabled flag or the auto-sort-cookie value. o Added some private typedefs to make the Hashtable methods' implementation code less verbose. * Some private members of the HashtableBase class had been declared protected by mistake. Fixed. * Fixed a bug in the Hashtable class that could cause a HashtableIterator to be updated improperly, if the Hashtable was resized during the iteration. * testhashtable's interactive test manually changed the ordering of its OrderedKeysHashtable on startup, breaking the table's automatic-sort functionality. Fixed. 7.13 Released 4/6/2019 - Added <, <=, >=, and > operators to the Queue class, to allow for easy lexicographical comparison of Queues. o Modified SharedFilterSessionFactory::IsAccessAllowedForIP() to be non-static, to avoid having to re-open the shared memory region on every call to the method. o Added const-qualifiers to local variables where appropriate. * Added a missing #include directive to DebugTimer.h 7.12 Released 2/5/2019 - Added a AddConstToRef() convenience-function to RefCount.h, as a counterpart to the existing CastAwayConstFromRef(). - NetworkInterfaceInfo::IsCopperDetected() now returns meaningful values under Windows. o Tweaked the code to avoid a few false-positive warnings from Clang Static Analyzer. o Removed SSLSocketDataIO.{cpp,h} from the include XCode project since it is typically not necessary and breaks the build if OpenSSL isn't installed on the host Mac. 7.11 Released 1/7/2019 o Queue:GetWithDefault() methods that take a default-value argument (by-reference) now return their return-value by-value rather than by-reference, to avoid any possibility of returning a dangling reference if they are called with a temporary-object argument. o Hashtable:Get*WithDefault() methods that take a default-value argument (by-reference) now return their return-value by-value rather than by-reference, to avoid any possibility of returning a dangling reference if they are called with a temporary-object argument. * _MSC_VER was misspelled as MSC_VER in PseudoFlattenable.h, causing the code to fail to compile under MSVC2013. Fixed. * Fixed a bug in Mutex.h that would prevent MUSCLE_QT_HAS_THREADS from being correctly #defined if MUSCLE_AVOID_CPLUSPLUS11 wasn't set. * Fixed FileDescriptorDataIO.h to compile correctly under Windows in the case where it is the first muscle-include file to be parsed. * MuscleSupport.h now checks for the presence of _WIN32 (in addition to __WIN32__, etc) * Fixed an assertion failure that could be triggered inside DeadlockFinder_ProcessEnding() if MUSCLE_ENABLE_DEADLOCK_FINDER was defined. * Fixed some warnings generated by clang++ when -Wshadow is specified on the compile line. 7.10 Released 12/3/2018 - Under C++11 and later, the status_t type is now a class rather than a simple typedef for int32. It is used pretty much the same way as before, except now it provides better compile-time error-checking. - Under C++11 and later, the status_t type (and its values B_OK, B_ERROR, and B_NO_ERROR) are now part of the muscle namespace. - Added a WithoutNumericSuffix() convenience method to the String class. - The CMakeLists.txt file has been modified so that it is now usable by CMake 2.8.x and higher. o Functions in the C APIs have been modified to return type c_status_t (CB_ERROR or CB_NO_ERROR) rather than status_t, to avoid ambiguities with the new C++11 version of status_t in mixed C/C++11 programs. o BitChord::GetNumBitsInBitChord() and friends are now declared as static/constexpr rather than const methods, so that they can be called at compile-time now. o Replaced the MUSCLE_ENABLE_KEEPALIVE_API compile-flag with a new MUSCLE_DISABLE_KEEPALIVE_API flag (i.e. so that the socket-keepalive API is now enabled by default if neither flag is specified) o Doxygen documentation is now generated with C++11 enabled (before it was documenting the pre-C++11 API) * In the BitChord class, GetNumBytesInBitChord() and GetNumWordsInBitChord() were mis-named. Fixed. * Fixed a bug that affected MUSCLE subscriptions that included a QueryFilter: If a DataNode matched a subscription's node-path string, but its Message-payload didn't match the QueryFilter's criteria (at the time the subscription was created), then future modifications to the DataNode would not cause the subscriber to be notified even if the updated Message-payload did change to match the QueryFilter's criteria. * Modified StorageReflectSession::DoSubscribeRefCallback() to take its argument via an object-pointer rather than smuggling an integer delta-value to it inside a (void *). 7.03 Released 9/28/2018 - WarnOutOfMemory() now calls PrintStackTrace() (but not more often than once every 5 seconds, to avoid spamming) - BitChord::ClearUnusedBits() is now O(1) when compiled with C++11. o support/BitChord.h will now fall back to its legacy implementation if MUSCLE_AVOID_CPLUSPLUS11_BITCHORD is defined. (This define will automatically be set if MUSCLE_AVOID_CPLUSPLUS11 is defined) o Removed unnecessary call to ERR_print_errors_fp() from the SSLSocketDataIO constructor. * IPAddress's string-argument-constructor left its fields uninitialized in the case where SetFromString() failed. Fixed. * Fixed a bug in StorageRectSession::DoTraversalAux() that would cause the node-traversal to skip first node-name specified in the second (and later) path-strings in a Message. 7.02 Released 9/7/2018 - Added a function OptimizeMessageForTransmissionToMultipleGateways() that can be used to greatly reduce a server's RAM usage when it is going to send a large Message to multiple clients simultaneously. - Added a function IsMessageOptimizedForTransmissionToMultipleGateways() that will return true iff the specified Message has been tagged already. - Added a GetDistanceTo() method to the String class that returns the Levenshtein distance between two Strings. - Added a GetInitialMemoryUsage() method to the CompleteSystemSystem class. - Added a GetProcessMemoryUsage() function to MiscUtilityFunctions that returns the current process's approximate resident heap-size, in bytes. - Added a CreateConnectedSocketPair() convenience function to message_transceiver_thread.py. - Added AdoptRawDataArray() and ReleaseRawDataArray() methods to the Queue class, so that a Queue can operate using an externally-provided data-array if necessary. o Replaced some #defines in GlobalMemoryAllocator.h with inline functions instead, for more robust parsing. 7.01 Released 8/22/2018 - Added a EuclideanModulo() convenience function to MuscleSupport.h * Fixed some typos in the C++03 implementation of BitChord::FromWords() and BitChord::FromBytes() * Fixed a bug in Hashtable::MoveToPosition() that would cause it not to correctly position the target item when the specified position was in the latter half of the table's iteration-sequence. 7.00 Released 8/10/2018 - Rewrote the BitChord class to be much more powerful and easy to use (especially in conjunction with an enum of flag-names). The implementation now includes variadic methods (which are emulated via macros if C++11 isn't available), a PseudoFlattenable interface, and a number of new convenience methods. - BitChord now implements HashCode() and can therefore be used as a key-type in a Hashtable. - BitChord now implements CalculateChecksum(). - BitChord::ToHexString() now returns a constant-length hex string, instead of returning a string that starts only at the first non-zero byte. - Added a testbitchord.cpp test program to the tests folder. - CleanupDNSLabel() and CleanupDNSPath() now accept an optional second argument specifying additional characters that the filter should allow to remain in the returned String. - Under MacOS/X and BSD, MUSCLE sockets now have the SO_NOSIGPIPE socket-option automatically set on them, to avoid spurious SIGPIPE signals while running inside a debugger. - Updated PythonUtilityFunctions.cpp to be compatible with Python3. o Rewrote the CHILD_PROCESS_LAUNCH_BITS in the ChildProcessDataIO class to use a BitChord typedef (ChildProcessLaunchFlags) instead. Renamed them to CHILD_PROCESS_LAUNCH_FLAG_*. o Removed the "inherit file descriptors" member variable and arguments from the ChildProcessDataIO class and added a CHILD_PROCESS_LAUNCH_FLAG_INHERIT_FDS flag to replace it. o Added a (launchFlags) arg to the LaunchIndependentChildProcess() convenience methods in the ChildProcessDataIO class. o Changed the DATA_FLAG_* bits of the ByteBuffer class to an enum, managed by the EndianFlags BitChord typedef. Renamed them to ENDIAN_FLAG_* for clarity. o Renamed ByteBuffer::SetDataFlags() to ByteBuffer::SetEndianFlags() o BitChord is now implemented using uint32 words rather than unsigned-int words. o Modified the GetNetworkInterfaceInfos() function to take a GNIIBits argument instead of a uint32 (and renamed the GNII_* enums to GNII_FLAG_*) o Renamed BitChord::GetBit() to BitChord::IsBitSet() o Removed the inclusion of CoreFoundation/CFRunLoop.h from DetectNetworkConfigChangesSession.h since having it there could cause a namespace collision with Apple's Point class. o The ARRAYITEMS() templated method (in MuscleSupport.h) is now declared constexpr under C++11 and higher. o Moved the declaration of the Void class out of util/Hashtable.h and into support/Void.h o Modified the StringMatcher class to use BitChord instead of a uint8 to hold its internal flags. o Modified the FilePathInfo class to use BitChord instead of a uint32 to hold its internal flags. o Replaced the signal(SIGPIPE, SIG_IGN) call inside NetworkSetupSystem with a less problematic call to sigaction(SIGPIPE). o Added some documentation for the BitChord class to the MUSCLE-by-Example mkdocs pages. * Updated the Python3 code in the python3 folder to fix a couple of bugs (caused by code that was correct for Python2 but needed to be written differently for Python3) 6.91 Released 7/26/2018 - Added Pete Goodeve's Python3 port of MUSCLE's existing Python2 files (into the new python3 sub-directory) - Added a striphextermoutput utility program to the tests folder, since I'm tired of doing stripping hexterm output by hand. - hexterm now pays attention when you enter a blank line on stdin, and takes that as a hint to break up its output into separate Write() calls (useful when piping striphextermoutput's results back into hexterm, since otherwise the data for separate UDP packets could get combined into a single giant UDP packet, which isn't helpful) - hexterm now takes an optional "delay" argument; if the argument is specified (e.g. "delay=100 milliseconds"), then hexterm will insert a delay of that duration after each call to Write(). - MuscleSupport.h now uses stdint.h and inttypes.h by default as the basis for its int8/int16/int32/int64/etc typedefs, rather than trying to hand-roll them from the built-in C/C++ int/long types. If for some reason you can't use that, you can add the compiler flag -DMUSCLE_AVOID_STDINT to your command line and the old approach will be used instead. - Added SFINAE logic to the CloneObject() function (in Cloneable.h) so that (on C++11 and later) it now works correctly for objects that inherit Cloneable and also concrete objects that do not. - MuscleSupport.h now uses static_assert() to verify type sizes, if possible. - MicroMessage.c and MiniMessage.c now have pseudo-static-asserts so that they will generate compile-time errors if any of of the intN typedefs have the wrong size. - Added PutAndGetKey() convenience methods to the Hashtable class. (They work the same as PutAndGet(), except they return a pointer to the key object in the table, rather than the value object) * Fixed a bug that would cause Ref::Clone() to return a default-initialized item (rather than a clone of the existing item) if it was called on an object being managed by an ObjectPool. * Fixed a bug that would cause MuscleSupport.h to implicitly defined MUSCLE_AVOID_CPLUSPLUS11 under MSVC2014/2017. (I made the mistake of thinking that Microsoft would set the value of the __cplusplus macro correctly, but they do not) * The 32-bit/non-stdint typedefs for int32 and uint32 are now based on int (and unsigned int, respectively) rather than long/unsigned long. 6.90 Released 7/14/2018 - Updated SSLSocketDataIO.cpp to compile against newer versions of OpenSSL. - Added GetFirstKeyWithValue() and GetLastKeyWithValue() convenience methods to the Hashtable class. - CopyFile() now takes an optional third argument. The third argument, if set to true, allows CopyFile() to also recursively copy a directory, if the first argument is the path of a directory. o The MicroMessage API was designed in such a way that it was easy to accidentally dereference a misaligned pointer and invoke undefined behavior. I redesigned the API so that misaligned pointers are no longer used or exposed to the calling code, so that the MicroMessage API can now be used e.g. on ARM CPUs. * Fixed MSVC2017 compiler warning in PseudoFlattenable.h. * Fixed a buffer overflow in test/printsourcelocations.cpp * The C-based test programs in the test folder (microchatclient, minichatclient, microreflectclient, and minireflectclient) weren't handling socket-closed/EOF events correctly. Fixed. * Added some code to MiniMessage.c so that data fields will be longword-aligned even if ((sizeof(MMessageField)%8)!=0) * MFree() in the MiniMessage API was defined to return (void *) rather than (void), due to a copy/paste error. Fixed. * Updated the MUSCLE_ENABLE_MEMORY_TRACKING implementations of MAlloc(), MRealloc(), and MFree() to follow strict-aliasing rules. * IPAddressAndPort::WithInterfaceIndex() and IPAddress::WithInterfaceIndex() can now be called even when MUSCLE_AVOID_IPV6 is defined. 6.85 Released 5/29/2018 - Added logic to CMakeLists.txt so that if libz isn't installed on the build-system, it will automatically fall back to using the captive implementation in zlib/zlib. * Fixed a number of minor warnings that appeared when compiling with clang++ and all warnings enabled. * Fixed various typos and grammar problems in the MkDocs files. * Added a sanity-check to Message::Unflatten() so that a serialized Message with an impossibly-large entries-count field will error out cleanly, rather than attempt to allocate an impossibly-large Hashtable and exhaust the host's RAM. 6.84 Released 5/22/2018 - Added support for a -DMUSCLE_LOG_VERBOSE_SOURCE_LOCATIONS command-line switch so that the log output can contain full filename/line-number info, if desired. - ReflectServer::ServerProcessLoop() will now print warnings if it sees a session with no writeable socket and an outgoing Message queue that keeps getting longer and longer. o Added proper settings to the other build permutations in the .vcxproj files in the muscle-by-example/examples/vc++14 folder. * Win32AllocateStdioConsole() no longer attempts to redirect both stdout and stderr to the same file when a filename is supplied as its argument (because Windows apparently doesn't support that). Instead, a separate xxx_stderr.txt file is created to hold the stderr output. 6.83 Released 5/3/2018 - Rewrote the String::*IgnoreCase() methods to be more efficient (they no longer call ToLowerCase()). - Added Strcasestr() and StrcasestrEx() helper-functions to String.{cpp,h}. - Added a vc++14 sub-directory to the muscle-by-example\examples folder. It contains a .sln, .vcxproj files, and a BUILD_ALL.bat file, so that the "MUSCLE by Example" programs can be built using Visual Studio 2015 (or higher). * Added some missing .c and .cpp files to the the Visual Studio projects in the vc++14 folder so that the muscle-by-example example programs can all link. o Improved the Doxygen-documentation and code-formatting in String.{cpp,h} a bit. o Modified several of the muscle-by-example example programs so that they will compile and run even when C++11 support isn't enabled. o The Windows implementation of GetSystemPath() no longer calls PathRemoveFileSpecA(), which means programs including GetSystemPath() will no longer need to link to Shlwapi.lib. o Added a TimeSetupSystem class (part of CompleteSetupSystem) so that GetRunTime64() doesn't have to demand-calculate clock-frequencies on its first call. 6.82 Released 4/25/2018 o test/Makefile-mt no longer tries to compile testreflectsession except when executing on an OS that testreflectsession supports. o Did some minor editing and re-arranging of the "MUSCLE by Example" pages. o Replaced a number of `tags` in the MkDocs with [URLs](...) o Removed private-inheritance of CountedObject from all the classes that had it -- now they include a CountedObject private member variable instead. This was done only because all that private inheritance was cluttering up the Doxygen inheritance graphs. o Added a DECLARE_COUNTED_OBJECT macro to CountedObject.h so that any potential memory-overhead of CountedObjects can be eliminated in cases where object-counting is not desired. o Removed support for the -DMUSCLE_AVOID_OBJECT_COUNTING and added a -DMUSCLE_ENABLE_OBJECT_COUNTING macro in its place. (That is, the CountedObject class is now disabled-by-default and must be explicitly enabled in order to use it) o Added "MUSCLE by Example" documentation for MiscUtilityFunctions.{cpp,h} * Changed a number of `tags` in the MUSCLE-by-Example MkDocs source into [urls] so that the methods they mention can be quickly reviewed. * server/Makefile now specifies libmuscle.a after the main() .o file. * Fixed some gcc warnings in the tests folder (per Mika's suggestions) * UnparseFile() wasn't quoting keywords with spaces properly. Fixed. * Fixed the dependencies in the "MUSCLE by Example" examples' Makefiles. 6.81 Released 4/11/2018 - Added a "StorageReflectSession Message Types" section to the "MUSCLE by Example" mkdocs pages - Added a graphviz diagram to reflectserver.md - Added an "xcode" sub-directory that contains a muscle.xcodeproj project that compiles MUSCLE (contributed by Ruurd Adema) o Added an if-test to TarFileWriter::WriteOctalASCII() to avoid a spurious warning from gcc under Windows (reported by Mika) o muscled and admin now link to libmuscle.a instead of directly to the .o files. o Changed the first parameter of ConvertReturnValueToMuscleSemantics() from (int) to (long) in order to avoid compiler warnings. * Merged in a number of patches from Ruurd Adema that fix compiler warnings and errors in Doxygen comments. (Thanks Ruurd!) * muscle/server/Makefile was inappropriately including muscled.o in the libmuscle.a library. Fixed. * muscle/server/Makefile was specifying certain build-flags twice. Fixed. * Fixed a bug where the new item added by the zero-arguments versions of Queue::AddTail() and Queue::AddHead() was not being reliably default-initialized. o Added a note to the zero-argument Queue::AddTailAndGet() and Queue::AddHeadAndGet() methods' documentation that for POD ItemTypes, the value they return a pointer to may not be in an initialized state. 6.80 Released 4/2/2018 - Added the html/muscle-by-example tour MkDocs-source sub-directory. - Added ReadFrom() and WriteTo() methods to the PacketDataIO API (as convenient alternatives to calling SetPacketDestination() and/or GetSourceOfLastReadPacket()) - PlainTextMessageIOGateway now properly supports packet-based I/O. - MessageIOGateway, PlainTextMessageIOGateway, and RawDataMessageIOGateway all now support a PR_NAME_PACKET_REMOTE_LOCATION field which can be used to determine a UDP packet's source and/or destination when the gateway is being used in conjunction with a PacketDataIO. - Added a GetFieldTypeForName(const String &) convenience method to the Message class. - Added an IPAddress(const String &) constructor. - Added a GetPrettyTypeCodeString() function to Message.h, that returns a String object (instead of writing into a char[] buf), because really. - Added the IHostNameResolver interface, and the PutHostNameResolver(), RemoveHostNameResolver(), and ClearHostNameResolvers() functions, so that programs can add their own custom back-end functionality to the GetHostByName() function if they want to. - Added a GetHostByNameNative() function that does hostname lookup without any IHostNameResolver callbacks. - Added a Set() method to the IPAddressAndPort class. o Changed UDPSocketDataIO::Write()'s multi-target behavior to try to send to all targets even if some of the sends fail. o Moved SeekableDataIO and PacketDataIO subclasses into their own separate header files. o Updated test/testudp.cpp to support PlainTextMessageIOGateway also. * Fixed hexterm.vcproj to include some .cpp files that were missing. * muscled and libmuscle.a are now compiled without the -DMUSCLE_SINGLE_THREAD_ONLY and -DMUSCLE_ENABLE_MEMORY_TRACKING flags, so that libmuscle.a can be used as-is in more projects. * The PRINT_CALLS_PER_SECOND macro in TimeUtilityFunctions.h was broken, and printed more often than it was supposed to. Fixed. * Fixed a bug in SysLog.cpp's log-rotator code that could cause it to delete log-files prematurely under certain circumstances. * Fixed a bug that could cause Message::FindData(fn, B_ANY_TYPE, ...) to crash. * Added a number of additional .cpp files to the libmuscle.a file generated in the server folder. * Fixed an out-of-date comment in StdinDataIO.h * Half-specified numeric-range clauses in StringMatcher strings weren't being matched correctly. Fixed. * The default value of the (launchBits) argument in some of the ChildProcessDataIO::System() methods was set incorrectly. Fixed. 6.72 Released 1/5/2018 - MUSCLE_AVOID_CPLUSPLUS11 will now be #defined automatically inside MuscleSupport.h if it wasn't explicitly specified AND the __cplusplus preprocessor token is defined to a value smaller than 201100. - Added a muscleClearArray() templated convenience functions to MuscleSupport.h o Fixed a deprecation warning for kSCNetworkInterfaceTypePPTP in NetworkUtilityFunctions.cpp (MacOS/X only) o AtomicCounter.h and Mutex.h will now use the corresponding C++11 APIs in their internal implementation unless MUSCLE_AVOID_CPLUSPLUS11 is defined. o Added logic to detect XCode versions before 8.0 and auto-enable MUSCLE_AVOID_CPLUSPLUS11_THREAD_LOCAL_KEYWORD when they are detected, since XCode's clang++ didn't support the thread_local keyword before XCode 8.0. * Fixed compile error in AtomicCounter.h if C++11 was enabled and also MUSCLE_SINGLE_THREAD_ONLY was defined. 6.71 Released 11/3/2017 - Added a GetFieldType() method to the MessageFieldNameIterator class, for convenience. - Added a 'writeToStdout' argument to StdinDataIO's constructor so that StdinDataIO can optionally Write() data to stdout as well. (The argument defaults to false, for backwards compatibility) - SanitySetupSystem now verifies that sizeof(void*)'s value corresponds correctly to the presence/absence of the MUSCLE_64_BIT_PLATFORM macro, and panics if it doesn't. - Added constructors to MultiQueryFilter (and its subclasses) that take a std::initializer_list of child ConstQueryFilterRef's, for convenience. (requires C++11 or later to use) o CMakeLists.txt now includes the files in the dataio subdirectory as part of muscle.lib (except for SSLSocketDataIO.cpp, to avoid creating a hard-coded OpenSSL dependency) o Removed the 32-bit-specific implementation of CalculateHashCode64(); now the 64-bit is used on both 32-bit and 64-bit CPUs so that the function will give the same results regardless of platform. 6.70 Released 10/17/2017 - The ReflectServer class, if a DetectNetworkConfigChanges session is attached to it, will now automatically disconnect any non-local TCP connections just before the local computer goes to sleep, in order to avoid saddling any communicating peers with a moribund TCP connection. It will reconnect them, if possible, after the computer re-awakes. - The DetectNetworkConfigChangesSession constructor now takes an optional argument indicating whether or not its presence should enable the behavior described in the previous bullet-point. Defaults to true, but can be explicitly set false if you don't want the new behavior for some reason. - Added a back-end for the Thread class that uses C++11's std::thread - Added a back-end for the Mutex class that uses C++11's std::recursive_mutex - Added a back-end for the ThreadLocalStorage class that uses C++11's thread_local keyword. - Added a CMakeLists.txt file to the root directory, for those who prefer to compile a basic MUSCLE library and muscled using cmake (e.g. "cd muscle; mkdir _build; cd _build; cmake ..; make") - Added a IsSelfAssigned() convenience method to the IPAddress class. - Added FindFirstSessionOfType() and FindSessionsOfType() convenience methods to the ReflectServer class. o Moved the INetworkConfigChangesTarget interface out of DetectNetworkConfigChanges.h and into its own separate header file. o MUSCLE now requires a C++11 compiler by default. If you want to compile MUSCLE using an older (pre-C++11) compiler, you'll need to explicitly add -DMUSCLE_AVOID_CPLUSPLUS11 to your compile-flags. o MuscleSupport.h now automatically defines -DMUSCLE_USE_CPLUSPLUS11_THREADS if neither MUSCLE_AVOID_CPLUSPLUS11 nor MUSCLE_AVOID_CPLUSPLUS11_THREADS has been defined. o Checks for -DMUSCLE_USE_CPLUSPLUS11 have been removed, because C++11 is now the default compiler level. C++11-specific code is now guarded by #ifndef MUSCLE_AVOID_CPLUSPLUS11 instead. o Removed the "borland" subdirectory since it's obsolete. o Removed the deprecated SetReflectToSelf() and GetReflectToSelf() methods from the DumbReflectSession class. 6.62 Released 9/14/2017 o Moved constructor-arguments in the .cpp files to separate lines, for better diff-ability when they are modified. o Removed the overrides of String::StartsWith() that took an offset parameter, since it doesn't really make sense to check for a prefix with an offset. o Fixed some warnings flagged by clang++'s -Weverything option o Lots of miscellaneous Doxygen header-comment fixes and cleanup o Added a DoxyTemplates.h header file to serve as a repository of common class-member definitions, to avoid repetitive boilerplate. o Modified String::operator==() to call memcmp() rather than strcmp() * Improved portablereflectclient's string parsing a little. * Added "const" tag to several operators in the IPAddress class that were supposed to have it, but didn't. 6.61 Released 7/21/2017 - Added a WithInterfaceIndex() convenience method to the IPAddress class (for consistency with the IPAddressAndPort class's API) * Fixed a sign-casting error in ParseHumanReadableSignedTimeIntervalString() under Windows. Thanks to Mika Lindqvist for reporting this error. * Fixed potential crash in GetSystemPath() under MacOS/X. * Fixed the MCRASH macro to explicitly specify muscle::Crash() rather than just Crash(), so that it will work when called from other namespaces. 6.60 Released 6/22/2017 - Added SetPriority() and GetPriority() methods to the Thread class, to allow specification of the CPU-priority a Thread should run at. - SimulatedMulticastDataIO's unicast-ping-packets now contain location information about other members of the group, so that even if some packets get dropped, there is a good chance that all members will end up knowing about of all other members anyway. - Added define MUSCLE_CONSTEXPR that expands to constexpr iff MUSCLE_ENABLE_CPLUSPLUS11 is defined, or expands to nothing otherwise. - Some static methods in IPAddress and IPAddressAndPort are now tagged with MUSCLE_CONSTEXPR so that they can be evaluated at compile-time, if necessary. - Added an optional (roundUp) argument to the GetHumanReadableTimeIntervalString() functions. - Added SetPacketSendDestination() and GetPacketSendDestination() virtual methods to the DataIO class. - Added a ProxyDataIO class that passes through all calls verbatim to its held child DataIO object o Renamed XorDataIO to XorProxyDataIO, and made it a subclass of ProxyDataIO. o Renamed PacketizedDataIO to PacketizedProxyDataIO, and made it a subclass of ProxyDataIO. o Modified the UDPSocketDataIO class to contain the above two virtual methods instead of SetSendDestination() and GetSendDestination() o Renamed the GetSendDestinations() and SetSendDestinations() methods in UDPSocketDataIO to SetPacketSentDestinations() and GetPacketSendDestinations(), respectively. o Added a GetPacketSendDestination() method implementation to the SimulatedMulticastDataIO class. o Removed the GetInternalQThread() virtual method from the Thread class, since there is now a more general (non-Qt-specific) mechanism in the Thread class that can be used instead. o Rewrote SimulatedMulticastDataIO to be simpler and more robust; in particular it now only creates two UDP sockets instead of four. o Removed the FailoverDataIO class, since it didn't seem useful. o Renamed DataIO::GetPacketMaximumSize() to GetMaximuPacketSize() o Split the DataIO class into separate classes: DataIO for basic Read()/Write()-only I/O, SeekableDataIO for file-style I/O where the current-seek-position can be Seek()'d, and PacketDataIO for UDP-style packet-based I/O with explicit source and destination IP addresses. o Modified the various DataIO subclasses as necessary so that they now subclass from the appropriate interface. 6.50 Released 6/6/2017 - Added SimulatedMulticastDataIO, which simulates multicast communication via directed unicast. Useful for communicating multicast-style across a WiFi network, where real multicast communication doesn't work very well. - hexterm now supports a "wifi" keyword, which if specified along with the "udp=address:port" argument will replace the basic UDPSocketDataIO functionality with SimulatedMulticastDataIO, for testing purposes. - Added some additional Inflate() and Deflate() methods to the ZLibCodec class so that it can now write its output into an existing ByteBuffer object rather than allocating a new one from the byte-buffer-pool, if desired. - hexterm now accepts a "verifyspam" argument; if specified, hexterm will check incoming packets to see if they match the dummy-data format sent out by hexterm's "spamspersecond" feature, and if they do not, it will log an error message. - Added a GetHardwareType() method to the NetworkInterfaceInfo class. This method returns a NETWORK_INTERFACE_HARDWARE_TYPE_* value indicating what kind of network interface it is (e.g. Ethernet, WiFi, etc) - Added a GetNetworkHardwareTypeString() static method to the NetworkInterfaceInfo class. This returns a human-readable string describing the given NETWORK_INTERFACE_HARDWARE_TYPE_* - Added some MacOS/X-specific utility methods to the String class: SetFromCFStringRef(), ToCFStringRef(), and a String constructor method that takes a (const CFStringRef &) - The ip_address and IPAddressAndPort classes now implement the PseudoFlattenable interface to allow for easier handling. o Renamed the ip_address type to IPAddress, and made it a real class (and not a typedef'd alias for uint32) even when MUSCLE_AVOID_IPV6 is defined. ip_address is now a typedef'd alias to IPAddress, for backwards compatibility with old code. o The various convenience methods that could be called on an ip_address object (e.g. IsAddressIPv4(), IsAddressValid(), IsAddressMulticast(), etc) are now methods in IPAddress instead. o AtomicCounter now uses std::atomic internally, if MUSCLE_USE_CPLUSPLUS11 is defined. o PODSwapper and SwapContentsSwapper now check for the corner-case where the two objects passed in are actually the same object (and if so, they don't attempt a swap) o Added a GetSourceOfLastReadPacket() method to the DataIO interface. o UDPSocketDataIO::GetSourceOfLastReadPacket() is now virtual. o Moved the ip_address/IPAddress and IPAddressAndPort classes' declarations out of NetworkUtilityFunctions.h and into IPAddress.h o Moved the NetworkInterfaceInfo class (and its associated functions) out of NetworkUtilityFunctions.h and into NetworkInterfaceInfo.h * Fixed several places in the codebase that were inappropriately relying on CFStringGetCStringPtr() to return a non-NULL value, when in fact it is documented to return NULL sometimes. * hexterm now exits gracefully when stdin is closed. 6.42 Released 5/12/2017 - Added SetPerProcessRunTime64Offset() and GetPerProcessRunTime64Offset() calls, to support adding an artificial constant to the values returned by GetRunTime64(), for testing purposes - Added ParseHumanReadableSignedTimeIntervalString() and GetHumanReadableSignedTimeIntervalString() functions to TimeUtilityFunctions.h for better parsing of time-intervals that might be negative. - Added some new convenience methods to the Hashtable class: GetKeyAtWithDefault(), GetValueAt(), and GetValueAtWithDefault() o Modified the signatures of a few API calls (including MessageIOGateway::UnflattenHeaderAndMessage(), DeflateByteBuffer(), InflateByteBuffer, and the RawDataQueryFilter class) to take a (const ConstByteBufferRef &) rather than a (const ByteBufferRef &), as they don't ever need to modify the referenced ByteBuffer object anyway. 6.41 Released 3/23/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. o 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) 6.40 Released 2/10/2017 - Added templates 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. o Removed explicit Ref-type-casting code from a number of locations where it is no longer necessary. 6.38 Released 1/11/2017 - Added an Atoxll() function; it is the same as Atoull() except that it parses hexadecimal strings into uint64s rather 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. 6.37 Released 10/12/2016 o 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. 6.36 Released 6/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. o The POSIX implementation of PrintStackTrace() now calls backtrace_symbols_fd() rather than backtrace_symbols(), to avoid having to allocate memory when the heap might be corrupted. 6.35 Released 5/25/2016 o 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 6.34 Released 3/14/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. o Replaced the Thread class's writable GetInternalSocketSet() method with a more user-friendly API, including new methods RegisterInternalThreadSocket(), UnregisterInternalThreadSocket(), UnregisterAllInternalThreadSockets(), and IsInternalThreadSocketReady(). o 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. 6.33 Released 2/25/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) o DetectNetworkConfigChangesSession::SetEnabled(false) now also suppresses calls to ComputerIsAboutSleep() and ComputerJustWokeUp(). o 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 6.32 Released 12/3/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. 6.31 Released 8/27/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(). 6.30 Released 8/11/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. 6.23 Released 7/7/2015 - The StringMatcher class now has a IsPatternListOfUniqueValues() method that returns true iff the held pattern is a comma-separated list of non-wildcarded values. o NodePathMatcher::DoTraversalAux() was using a Queue as a cache, which could be inefficient due to O(N^2) lookups in certain cases. Replaced it with a Hashtable for better performance. o Optimized the NodePathMatcher algorithm to be more efficient with node-paths that include clauses that are long lists of comma-separated node names. * SharedFilterSessionFactory.cpp wouldn't compile if -DMUSCLE_AVOID_IPV6 was specified on the compile line. Fixed. 6.22 Released 6/11/2015 - Added an IsWaitingForEvents() method to ReflectServer class, so that a (user-supplied) watchdog thread can observe when the ReflectServer is blocked waiting for I/O vs when it is doing something. - Added Mika's vc++14 subdirectory, which contains Visual C++ project files for Visual Studio 2015. - DataNode::GetAncestorNode() now takes an optional second argument that tells it what to return if the ancestor node isn't found. o Added some more Cygwin/MinGW compatibility changes contributed by Mika Lindqvist. o Rewrote some of the node-traversal callback methods so that they no longer pass an integer argument by casting it to (void *). * Tweaked various files to fix warnings reported by cppcheck 1.69. * The stdout-display in qt_muscled wasn't read-only. Fixed. 6.21 Released 5/14/2015 o Merged in Mika Lindqvist's patch to make the StackWalker code use less stack space. o Merged in Mika Lindqvist's patches for better Cygwin compatibility. * Made the StackWalker code a bit more robust. * Merged in Mika Lindqvist's patch to the VC++12 projects to link debug builds against the MultiThreadedDebug run time library rather than the MultiThreaded library. * Fixed a couple of const-correctness issues in the StackWalker code. o Modified the Windows implementation of GetNetworkInterfaceInfos() to not specify an interface index for IPv6 network device address ::1, as doing so causes UDP-packet-routing problems under Windows 7. 6.20 Released 4/20/2015 - Added a new sub-folder besupport/admin_gui. It contains Fredrik Modéen's GUI shell for more easily running muscled under BeOS or Haiku. - Added new MUSCLE-specific versions of some potentially-insecure (per Microsoft) C functions to MuscleSupport.h: muscleFopen(), muscleStrcpy(), muscleStrncpy(), muscleSprintf(), and muscleSnprintf(). These get expanded out to the appropriate system-specific equivalent, so that e.g. under Windows we can use the CRT-secure Windows-only equivalents, while not having to put #ifdefs all over the code to keep it compiling elsewhere. - Added Visual C++ 2013 project files, courtesy of Mika Lindqvist (in the new "vc++12" subfolder) o Renamed the vc++ subfolder to vc++8 to make it more obvious that the project files it contains are for Visual Studio 2008. o MUSCLE classes that should not be subclasses are now tagged with the MUSCLE_FINAL_CLASS keyword so that when compiled with -DMUSCLE_USE_CPLUSPLUS11 the compiler will produce a compile-time error if they are subclassed. o Modified the QueueGatewayMessageReceiver and StringMatcherQueue classes to no longer subclass from the Queue class, since subclassing from Queue is no longer allowed. Instead, they now include a Queue object as a member variable and provide accessors to that object. o Modified the ObjectPool class to no longer subclass the ObjectNode internal class from the templated-type, since the templated-type might now be marked as "final". o Replaced various of the aforementioned calls with their muscle*() equivalents in the codebase. o Merged in some patches contributed by Mika Linqvist to avoid CRT security warnings when compiling under MSVC 2013. o Removed all calls to strcat() and strncat(), as their string truncation semantics are too difficult for me to reason about reliably. The rewritten code is also generally more efficient. o Modified DefaultFileLogger::CloseLogFile() to reduce its stack usage. o Modified GetNetworkInterfaceInfos() to not specify an interface index for IPv6 network device address ::1, as doing so causes UDP-packet-routing problems under MacOS/X. * Fixed a const-correctness problem in ConvertMessages.cpp. * Removed a compiler warning (from SysLog.cpp) about GetVersionA() not working usefully under Windows 8 and higher. * Applied Mika Lindqvist's patch to fix some potential memory leaks in regcomp.c * Applied Mika Lindqvist's patch to make the Windows "StackWalker" stack-trace-generation routine Unicode-compliant. 6.12 Released 4/6/2015 - The Python message_transceiver_thread class will now fall back to connecting via IPv4 if the supplied hostname cannot be expanded to an IPv6 address (and vice versa). o Added a NotCopyable base class to various classes (Socket, DataNode, AbstractReflectSession, etc) so that the compiler will verify that they are not being copied. o The StringMatcher class now interprets any simple wildcard string starting with a backtick character (`) as indicating a non-simple regex string. That way it is possible to use the standard regex functionality, if desired, in contexts that otherwise provide no way to indicate that a string is meant to be a full regex string and not a simple wildcard string (e.g. in MUSCLE subscription strings) o Tweaked the codebase to get rid of a number of style problems and minor errors that were reported by cppcheck. * Added a patch to the captive regex library to fix a potential int32-overrun in regcomp(). Thanks to Mika Lindqvist for supplying me with the patch. * Merged in some patches from Mika Lindqvist to avoid some warnings when compiling in a 64-bit environment. 6.11 Released 2/2/2015 - When compiled under Windows, SetupSystem.cpp now contains #pragma commands so that necessary Windows-libraries will be automatically linked in. This means the user no longer has to spend time chasing down so many linker errors when setting up a new project file. o MutexGuard's argument is now a const reference, since Mutex::Lock() and Mutex::Unlock() are const methods. o Removed AbstractReflectSession::GetDefaultHostName() and replaced it with a new method named AbstractReflectSession::GenerateHostName(). The new method lets the session subclass choose a custom hostname for the session even if the IP address determination didn't fail. o Added some private/unimplemented method overloads for MessageTransceiverThread::AddNewConnectSession() and QMessageTransceiverHandler::SetupAsNewConnectSession() so that if the caller tries to call these methods with timeout-values but forgets to include the (expandLocalhost) argument, the error will be caught at compile-time rather than causing unexpected run-time behavior. 6.10 Released 12/12/2014 - The DetectNetworkConfigChangesSession class now has ComputerIsAboutToSleep() and ComputerJustWokeUp() callback methods that are called at the times indicated by their names. Currently this functionality is implemented only under MacOS/X and Windows. o Added work-arounds for gcc-3.x SFINAE incompatibilities to MuscleSupport.h o Updated the muscle.dox file using doxygen -u so that it is now up-to-date (as of Doxygen 1.8.8) * If a string like "for 10 seconds" was passed to ParseHumanReadableTimeIntervalString(), the "for" prefix would cause the returned value to be twice what it was expected to be. Fixed. 6.09 Released 11/3/2014 - Added a (preferIPv6) argument to GetHostByName(). If left as true (the default value), GetHostByName() will prefer to return an IPv6 address over an IPv4 address. - Added support for a DEBUG_LARGE_MEMORY_ALLOCATIONS_THRESHOLD compiler-flag into GlobalMemoryAllocator.cpp. When this flag is set to a value (in bytes), any memory allocations greater than the value will result in a message and a stack trace being printed to stdout. - When MUSCLE_USE_CPLUSPLUS11 is defined, the PODHashFunctor class will provoke a compile-time error if the program tries to use a struct or class as a KeyType in a Hashtable and the struct/class does not have a "uint32 HashCode const" method defined. (Previously the code would compile without error, and then hashing errors would occur at runtime due to the object's padding bytes being uninitialized) * The MCRASH() macro now calls abort() rather than assert(false), so that a crash will actually occur, even if the code was compiled with -DNDEBUG. o The Windows implementation of MCRASH() now calls RaiseException(), so that the crash will behave more like an actual caused-by-a-bug crash (in particular, a Windows Structured Exception will be raised) o Updated SendDataUDP() to work around a "feature" in OS/X 10.10 (aka Yosemite) that causes setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF) to fail when setting the socket's interface-index value back to 0. 6.08 Released 10/10/2014 - Added a ShrinkToFit() convenience method to the Queue, Hashtable, and String classes. This method shrinks the object so that the amount of memory it has allocated internally matches the size of the data it is actually holding. - Hashtable::EnsureSize() and Queue::EnsureSize() now take an optional (allowShrink) argument, that (if set to true) allows the object's internally-allocated array to be reallocated smaller if it is larger than necessary. o Tweaked the buffer-expansion behavior of the String class to be a bit more efficient. * Added a guard against a potential infinite recursion that could occur while logging an "OUT OF MEMORY" error after a memory allocation failure, if a LogCallback tried to allocate memory. 6.07 Released 9/18/2014 - Added a GlobalPrintRecyclersToStream() method to the AbstractObjectRecycler class, for better debugging and analysis of the ObjectPool's memory usage. - Added an abstract PrintToStream() method to the AbstactObjectRecycler class, and a concrete implementation of that method to the ObjectPool and ThreadPool classes. - Added a testobjectpool.cpp test program to the tests folder, as a quick sanity check for the ObjectPool class. - Java performance improvement from Bryan Varner: Switched to a direct byte buffer, which is allocated by the OS outside of the GC's managed space. - Java performance improvement from Bryan Varner: Scoped the receiving byte buffer to the receiver, which cut down on a lot of time spent allocating short-lived buffers. - Java performance improvement from Bryan Varner: Added a constructor for the MessageReceiver to allocate it's buffer to the same size as the sockets underlying buffer and made use of the call where possible. - Added a GetObjectClassName() method to the ObjectPool class. - The GetNetworkInterfaceInfos() function now supports a new bit named GNII_INCLUDE_UNADDRESSED_INTERFACES, which tells it to return even network interfaces with no IP address. - The default value of the (includeBits) argument to GetNetworkInterfaceInfos() is now GNII_INCLUDE_ALL_ADDRESSED_INTERFACES rather than GNII_INCLUDE_ALL_INTERFACES, to reflect the nuance that was added above; the default behavior is unchanged, though. - When -DMUSCLE_USE_CPLUSPLUS11 is defined, muscleMin() and muscleMax() now use variadic templates so that they can accept any number of arguments (rather than just up to five). o Java fix from Bryan Varner: Updated the handling code for NotEnoughDataExceptions to no longer rely on the position of the buffer (but rather look at the buffer limit, or the amount previously read into the buffer) -- which basically makes the above change unnecessary, but I'm paranoid. o Changed the Message, Queue, Hashtable, and String classes so that when they are set equal to an empty/default object, they now free any large dynamically-allocated buffer they may be holding. This avoids excessive memory usage by objects that have been returned to an ObjectPool after being used to hold large amounts of data. o Modified muscleMin(), muscleMax(), muscleSgn(), muscleClamp(), and musclAbs() to take arguments and return by value rather than by const-reference. * Java fix from Bryan Varner: Fixed a bug causing communication failures in the NIO message unflattening. * Java fix from Bryan Varner: Prior to throwing a NotEnoughDataException the position of the buffer wasn't being updated in MessageIOGateway and JZLibMessageIOGateway. 6.06 Released 8/15/2014 - ParseHumanReadableTimeIntervalString() can now parse strings where only the time-unit is specified. (e.g. "second" now returns 1000000) - Added GetInternalThreadPulseTime(), InternalThreadPulse(), WriteToMainThread(), and ShutdownInternalThread() methods to the AsyncDataIO class, so that it can be subclassed for use in impersonating a "live" socket, using test data internally generated inside its I/O thread. o Added code to testbytebuffer.cpp, so that if a filename is passed as an argument, the contents of the specified file will be printed to stdout in annotated-hex format. o Added support for a -DMUSCLE_AVOID_XENOMAI flag, to be used when compiling with -DTARGET_PLATFORM_XENOMAI but we don't want MUSCLE to use Xenomai anyway. * Merged in Augustin Cavalier's patch to get MUSCLE to compile again under Haiku. * Modified the Queue code to avoid a static-analyzer warning. * Fixed a valgrind hit in AbstractReflectSession::Reconnect(). * Fixed a bug in AsyncDataIO that would cause it to hang when being shut down. * Fixed a bug that could cause a QueryFilter's replacement ConstMessageRef object to be ignored in certain circumstances. 6.05 Released 6/27/2014 - Upgraded the captive zlib implementation to v1.2.8. o Moved public repository from FreeCode to GitHub, because FreeCode no longer accepts release announcements. o Renamed LICENSE.txt to LICENSE, since that's how GitHub likes the license file to be named. * Merged in Mika Lindqvist's patch to avoid some truncation warnings for strlen() calls under 64-bit Visual C++. 6.04 Released 6/11/2014 - Added a public GetParametersConst() method to the StorageReflectSession, for easier debugging. * Fixed a bug that prevented the PR_COMMAND_REMOVEPARAMETERS handler from removing parameters that had escaped wildcard characters in their names. 6.03 Released 6/2/2014 - Added a convenience method muscleArrayIndexIsValid() that returns true iff the specified numeric index is a valid index into the specified array. - Added a CloseCurrentLogFile() function that can be used to force the file-logger to close any log file that it currently has open. - Added a SetSendDestinations() method to the UDPSocketDataIO class, for convenience. - The Launch*() and System*() methods in the ChildProcessDataIO class now take an optional directory-path argument so that you can specify the current working directory of the child process. - Added move-constructors and move-assignment operators to the Ref and ConstRef classes (available only when MUSCLE_USE_CPLUSPLUS11 is defined, of course). - Added a Reset() method to the PointerAndBool class. - Added a SwapContents() method to the PointerAndBool class. - Added RemoveHeadMulti() and RemoveTailMulti() convenience methods to the Queue class. o Queue::GetArrayPointer() now makes sure to set (retLength) to 0 when it returns NULL. * Under Windows, GetConstSocketRefFromPool() now automatically sets the don't-inherit flag on any sockets passed to it. This avoids problems caused by child processes unintentionally holding sockets connections open in the parent process. * Fixed a bug in Queue::EnsureSizeAux() that would cause a bogus extra item to be added to the end of the Queue if the (setNumItems) argument was set to true. * The MacOS/X implementation of DetectNetworkConfigChangesSession would fail to notify its calling code about a changed network configuration if the network change did not include any IP address changes. Now it does provide a notification for that scenario as well. 6.02 Released 4/2/2014 - Added optional (addHeaderBytes) and (addFooterBytes) arguments to the DeflateByteBuffer() utility functions. - Added an implementation of GetByteBufferFromPool() that takes a DataIO as an argument, for easy reading in of files, etc. - Added a NybbleizeData() implementation that takes a pointer and length argument rather than a ByteBuffer object. - Added an AreKeySetsEqual() convenience method to the Hashtable class. This method checks for equal key-sets while ignoring the values in the two Hashtables. - Added WithoutPrefixIgnoreCase() and WithoutSuffixIgnoreCase() convenience methods to the String class. - Added some missing convenience overloads for HexBytesToString(). - CanWildcardStringMatchMultipleValues() now ignores dashes in the string, since they only have meaning when enclosed in brackets -- and if there are brackets in the string, those will be sufficient to cause CanWildcardStringMatchMultipleValues() to return true. o Renamed CanRegexStringMatchMultipleValues() to CanWildcardStringMatchMultipleValues(), as it is really examining the simplified wild-card syntax and not the official regex syntax. o Several locations that were calling HasRegexTokens() to decide if it was worth doing pattern-matching with a key-string now call CanWildcardStringMatchMultipleValues() instead. o DataNode::Reset() now deletes any metadata structures the DataNode may have accumulated, rather than simply clearing them. This saves RAM, and also ensures that recycled DataNodes will act exactly the same as newly created ones. * The MemMem() function did not return correct results in all cases. Rewrote it to work correctly. 6.01 Released 1/7/2014 - Added a PrependWord() convenience method to the String class. - Added WithReplacements() convenience methods to the String class. - Added a SetExplicitDelayMicros() method to the DetectNetworkConfigChangesSession class. - Added a IsCopperDetected() method to the NetworkInterfaceInfo class, so that code can tell whether or not a Ethernet jack has a cable plugged in to it. - Added a "quietsend" argument to hexterm. o The NetworkInterfacesChanged() virtual method in the DetectNetworkConfigChangesSession class has been changed to take an argument that calls out which network interfaces in particular have changed. This functionality is currently only implemented under Linux, MacOS/X and Windows. For other OS's the argument will always be an empty list. * Fixed a bug in the Linux implementation of DetectNetworkConfigChangesSession that could cause a segmentation fault if recvmsg() returned an error (e.g. due to a signal being received). 6.00 Released 10/14/2013 - Rewrote the SSLSocketDataIO class to work better with non-blocking I/O (in conjunction with the new SSLSocketAdapterGateway class). - Added implementations of SSLSocketDataIO::SetPrivateKey() and SSLSocketDataIO::SetCertificate() that take a ByteBuffer as an argument. - Added an SSLSocketAdapterGateway class that is used to manage OpenSSL's internal state machine when using an SSLSocketDataIO class with your gateway. - Added SetSSLPrivateKey() and GetSSLPrivateKey() methods to the ReflectServer class, for easier enabling of SSL authentication on all incoming TCP connections. These methods are available iff MUSCLE_ENABLE_SSL is defined. - Added SetSSLPublicKeyCertificate() and GetSSLPublicKeyCertificate() methods to the ReflectServer class, for easier enabling of SSL authentication on outgoing TCP connections. These methods are available iff MUSCLE_ENABLE_SSL is defined. - Added SetSSLPrivateKey() and SetSSLPublicKeyCertificate() methods to the MessageTransceiverThread class, for easier enabling of SSL functionality when using threaded I/O. - Added an ssl_data folder with some info on generating OpenSSL public/private keypairs, and an example keypair for use in testing OpenSSL. - When MUSCLE_ENABLE_SSL is defined, muscled now accepts an optional 'privatekey=filename' argument. When specified, SSL mode will be enabled and muscled will only accept incoming TCP connections that present public keys that match this private key/certificate. - When MUSCLE_ENABLE_SSL is defined, portablereflectclient and qt_example will now accept an optional 'publickey=filename' argument. When specified, SSL mode will be enabled and these clients will connect to muscled using OpenSSL and present this file as their credentials. - Added an "Animate" checkbox to the qt_example demo. Checking it causes the window to move its indicator around automatically. This is fun and also useful if you want to test a scenario where multiple clients are generating traffic simultaneously. - Made the qt_example demo prettier. - Renamed the C++11-helper macros in Hashtable.h and Queue.h to make them less likely to collide with other packages' macros. * Fixed some minor errors in the SSLSocketDataIO class. o Renamed SSLSocketDataIO::SetKey() to SetPrivateKey(). o Renamed SSLSocketDataIO::SetCertificate() to SetPublicKeyCertificate(). o AbstractMessageIOGateway::SetDataIO() is now a virtual method. 5.92 Released 9/20/2013 - Improved support for C++11 move-semantics in the Queue and Hashtable classes (enabled only when -DMUSCLE_USE_CPLUSPLUS11 is defined) - 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) - Added a PrintAndClearStringCopyCounts() function which will print out the String-operation data collected above. - Added some SFINAE magic to muscleSwap() so that it will swap by calling SwapContents() when possible, rather than by copying to a temporary object. - Added an initializer-list constructor and overload of AddTailMulti() to the Queue class (available only when -DMUSCLE_USE_CPLUSPLUS11 is defined, of course) o Renamed the Queue and array overloads of Queue::AddTail() to AddTailMulti(), to avoid conflicts with the new C++11 template parsing support. o Renamed the Queue and array overloads of Queue::AddHead() to AddHeadMulti(), to avoid conflicts with the new C++11 template parsing support. o Replaced MCRASH_IMPL macro with a call to assert(false). * A little more Android-compatibility tweakage. * Many of the programs in the tests folder weren't compiling under C++11. Fixed. * Fixed several potential bugs that were detected by clang's static analysis tool. 5.91 Released 9/2/2013 - Added EnsureCanPut() convenience method to the Hashtable class. - Added EnsureCanAdd() convenience method to the Queue class. o Changed DoMutexAtomicIncrement() to be an inline function to make calling it more efficient. * Changed QMessageTransceiverThread and QAcceptSocketsThread to call QCoreApplication::postEvent() rather than QApplication::postEvent(), to allow for non-GUI Qt apps. * Updated the Beginner's Guide document to reflect MUSCLE's improved UDP support. * Merged in some Android compatibility changes provided by Jean-François Mullet. * Use of the MUSCLE_USE_MUTEXES_FOR_ATOMIC_OPERATIONS compile flag would cause MUSCLE to crash on startup due to an order-of-operations issue. This has been fixed now. * 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. 5.90 Released 8/6/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. o Modified the Hashtable class so that the _iterHead, _iterTail, and _freeHead member values are now uint32s rather than pointers, to reduce memory usage. o 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. o 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. o 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. o The CalculateChecksum() methods in Message.cpp have been modified to be more robust in detecting data transposition differences. o 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. o 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. o Added a udpproxy.vcproj file to the tests folder, to help compile udpproxy under Windows. o Message:Flatten() now iterates over the fields in the Message once, instead of twice. o GetCurrentThreadID() is now an inline function, since it may now get called often by HashtableIterator. o 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. 5.85 Released 7/2/2013 - 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. o 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. * 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. 5.84 Released 4/20/2013 - The StringMatcher class's numeric-range syntax has been extended so that you can now specify multiple ranges. For example, "<19-21,25,30-50>" 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. o 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. 5.83 Released 11/11/2012 - Added convenience versions of InflateByteBuffer() and DeflateByteBuffer() that take a ByteBufferRef as an argument. o Removed some obsolete/unused methods (EnsureBufferSize() and FreeLargeBuffer()) from the AbstractMessageIOGateway class. o Fixed some typos in the comments in the delphi subfolder. * The Hashtable class no longer generates warnings when compiled under MSVC with -DMUSCLE_AVOID_MINIMIZED_HASHTABLES defined. * Fixed a bug in IPAddressAndPort::ToString() that caused IPv4 address strings to be formatted ambiguously when (preferIPv4Style) was set to false. 5.82 Released 10/1/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. 5.81 Released 9/13/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) o 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. 5.80 Released 8/30/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. o 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. 5.72 Released 6/27/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. 5.71 Released 6/11/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). o Renamed MUSCLE_AVOID_REFCOUNT_BITSTUFFING to MUSCLE_AVOID_BITSTUFFING, since bit-stuffing is no longer specific to the RefCount class. 5.70 Released 5/8/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. 5.69 Released 4/18/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. o 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. o Tweaked the .pro files in the qtsupport folders to make them compatible with Qt 5.0. o 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. 5.68 Released 3/23/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. o 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. 5.67 Released 2/3/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. o Cleaned up the Python code to avoid pychecker warnings o 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. 5.66 Released 1/5/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. o AbstractMessageIOGateway::AddOutgoingMessage() is now virtual. o 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. 5.65 Released 12/22/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. 5.64 Released 12/13/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. o Modified all MUSCLE code to use a SocketMultiplexer object rather than calling select() or poll() directly. o 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. 5.63 Released 12/1/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. o 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) 5.62 Released 11/2/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. o 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. 5.61 Released 9/28/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. o 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. 5.60 Released 9/19/2011 - Added a qt_advanced_example directory to the qtsupport folder to demonstrate more advanced usage of the QMessageTransceiverThread class. See the README.TXT and the diagram PNG in that directory for details. - Added a TamperEvidentValue class (in support/TamperEvidentValue.h) - ThreadWorkerSession and ThreadWorkerSessionFactory objects now have (and use) a SendMessageToSupervisorSession() method for sending messages to their supervisor. This is more efficient and less error-prone that calling BroadcastMessgeToAllSessions(), and relying on non-supervisor recipients to ignore the Messages that weren't meant for them, as was done previously. - Added SetForwardAllIncomingMessagesToSupervisor() and IsForwardAllIncomingMessagesToSupervisor() methods to the ThreadWorkerSession, ThreadWorkerSessionFactory, and MessageTransceiverThread classes. These methods govern how Messages incoming from remote peers should be handled. o Retired the MUSCLE_USE_IPV6 compiler option, since enabled IPv6 support is now the default. If you want to disable IPv6 support, you'll need to specify -DMUSCLE_AVOID_IPV6 instead. o ThreadSupervisorSession::SendMessageToWorkers() is now protected rather than private. o MessageTransceiverThread::GetNextEventFromInternalThread now passes PR_RESULT_* Messages to the caller, so that it's possible to use a MessageTransceiverThread as if it it were a client to the local MUSCLE thread, if desired. o QMessageTransceiverThread now calls SetDoLogging(false) inside CreateReflectServer() rather than afterwards, so that subclasses can easily re-enable logging if they want to. * Gave the README.TXT file a badly needed rewrite/update. * Tweaked the doxygen.dox file to yield better-looking Doxygen HTML documentation. * genDocs.sh now automatically extracts the current MUSCLE version number from MuscleSupport.h, so it's no longer necessary to manually update the muscle.dox file for each MUSCLE release. 5.57 Released 9/16/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. 5.56 Released 9/4/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. o Added checks for (sizeof(float)==4) and (sizeof(double)==8) to the SanitySetupSystem constructor. o PrintHexBytes() and LogHexBytes() now take a ConstByteBufferRef rather than a ByteBufferRef, since they don't ever need to modify the ByteBuffer they receive. o 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. o DataNode::GetIndex() now returns a (Queue *) rather than a (Queue *). o DataNode::ReorderChild() now takes a DataNodeRef rather than a reference to a DataNode object. o Added util/FilePathInfo.cpp, and Moved the non-trivial FilePathInfo method bodies into it. o 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. 5.55 Released 7/28/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. 5.54 Released 6/24/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. o Reduced sizeof(Queue), sizeof(Hashtable), and sizeof(ObjectPool) by removing their default-object member items and adding calls to GetDefaultObjectForType() instead. o Replaced the various get-default-object convenience methods (GetEmptyString(), GetEmptyMessage(), etc) with inline call-throughs to GetDefaultObjectForType(). 5.53 Released 6/16/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. o Reduced sizeof(String), by by employing a union to reuse the bytes used for referencing small and large char arrays. o 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) o Reduced sizeof(DataNode) by making the subscribers table demand-allocated, rather than a member variable. o 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. 5.52 Released 6/8/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. o 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. 5.51 Released 5/23/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. o 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) o 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. 5.50 Released 4/18/2011 - Added a qt_muscled_browser subfolder to the qtsupport folder. qt_muscled_browser is a GUI MUSCLE database browser, based on code contributed by Jean-François Mullet. - Added GetFirstKeyWithDefault(), GetLastKeyWithDefault(), GetFirstValueWithDefault(), and GetLastValueWithDefault() convenience methods to the Hashtable class. - Added a RemoveWithDefault() convenience method to the Hashtable class. - Added a CountAverageLookupComparisons() method to the Hashtable class, to help determine the hashing performance of various hash functions. - Added a -DMUSCLE_WARN_ABOUT_LOUSY_HASH_FUNCTIONS preprocessor define, which will cause the Hashtable reallocator to calculate the hashtable's average lookup comparisons value after every hashtable resize, and complain if the average lookup count is too high. - Added 3-argument constructors to the AndOrQueryFilter and NandNotQueryFilter classes. - Added regex/FilePathExpander.{cpp,h}. These files contain a single function, ExpandFilePathWildCards(), which expands wildcarded file paths into a list of non-wildcarded paths, similar to shell expansion. - Added test/testmatchfiles.cpp, a unit test for the ExpandFilePathWildCards() function. o Moved the boolean "isAnd" argument to the front of the arguments list for the AndOrQueryFilter constructors. o Removed the -DMUSCLE_COLLECT_HASHTABLE_COLLISION_STATISTICS preprocessor define, since the new -DMUSCLE_WARN_ABOUT_LOUSY_HASH_FUNCTIONS replaces it. o PortableReflectClient now includes a string showing the current time when you 's'et a node, so it's easier to see the node change in other clients. * FilePathInfo::SetFilePath(NULL) would crash. Fixed. * ChildProcessDataIO::System() and ChildProcessDataIO::LaunchChildProcess() weren't NULL-terminating their argv arrays. Fixed. 5.43 Released 3/29/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. 5.42 Released 2/26/2011 - Added SetEnabled() and IsEnabled() methods to the DetectNetworkConfigChangesSession class. o 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. 5.41 Released 2/2/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. o 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. 5.40 Released 12/20/2010 - Added various time-units-conversion functions to TimeUtilityFunctions.h - Added a few time-related constants to TimeUtilityFunctions.h - Added a DetectNetworkConfigChangesSession class, which can be used to install a handler that is called whenever the host computer's networking configuration has changed. - Added testnetconfigdetect.cpp to the tests folder, as a simple test/example of using the DetectNetworkConfigChangesSession class. - Added a TelnetPlainTextMessageIOGateway class, that works similarly to PlainTextMessageIOGateway, except that it filters out any telnet-protocol control codes that get sent from the client. o Made it a no-op to call AbstractReflectSession::EndSession() on a session that isn't attached to a server. (Previously it would trigger an assertion failure, but an unattached session is already effectively ended so there's no point in crying over it) o Code cleanup: Magic-number time-unit conversions in several places now use the new time-conversion functions instead, for clarity. o Simplified the SharedUsageLimitProxyMemoryAllocator. It no longer maintains a running sum of the total memory usage of the daemon set, but rather recalculates the current sum when needed. * The StringMatcher class's copy constructor wasn't initializing its _bits field to zero, which could cause undefined behavior. Fixed. * StringMatcher::SetPattern() didn't clear the negate-bit when setting a non-simple (aka full regex) pattern. Fixed. 5.35 Released 12/5/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. o Changed QueryFilterRef arguments to ConstQueryFilterRef where appropriate. o Replaced the (usePty) boolean in ChildProcessDataIO::Launch*() method with a launchBits bit-chord, so that multiple options can be specified. o 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. 5.34 Released 10/19/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 file descriptors, respectively (and thus suppress its output from then on) - DebugTimer can now accept a negative logLevel parameter, which will force it to output using printf() instead of LogTime(). - Added a GetSystemMemoryUsagePercentage() function to MiscUtilityFunctions.{cpp,h} 5.33 Released 8/31/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. o Changed String::CompareToIgnoreCase() to call strcasecmp() rather than calling ToUpper() on both strings. o 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 address strings. * ParseArgs() now un-escapes any escaped quote marks. * The micromuscle Java classes were still packaged under com.lcs.*. Changed them to com.meyer.* 5.32 Released 7/22/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. o 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. 5.31 Released 6/7/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. o 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. o 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. o 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. 5.30 Released 5/7/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} o GetEmptyMessageRef() now returns a ConstMessageRef instead of a MessageRef, to ensure that the returned Message is not (easily) modified. o GetEmptyByteBufferRef() now returns a ConstByteBufferRef instead of a MessageRef, to ensure that the returned ByteBuffer is not (easily) modified. o 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. o 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. 5.23 Released 4/22/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. o 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. o Re-organized the GlobalSocketCallbacks so that they all happen immediately after the socket is created. o Changed the "Couldn't disable V6-only mode" message to MUSCLE_LOG_DEBUG. o 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. 5.22 Released 3/3/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. o Removed MUSCLE_CUSTOM_ATOMIC_TYPE support from the AtomicCounter class, since it wasn't useful and was cluttering up the code. o 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. 5.21 Released 1/21/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 5.20 Released 12/29/2009 - PrintStackTrace() is now implemented under MSVC/Win32, using Jochen Kalmbach's StackWalker class. - The debugcrashes command line argument is now supported under MSVC/Win32; with it specified, crashes will cause PrintStackTrace() to be called, and therefore a stack trace to be printed to stdout. - Added a GetTotalDataSize() method to the Hashtable and Queue classes, so that it's possible to query how much RAM the container is using. - The Message::*Flat() methods are now templated so that the object you pass in to them doesn't have to be a subclass of Flattenable... it just have to have necessary methods declared. This lets you save memory on small flattenable objects since they no longer need a vtable pointer. - Added a GetFlattenedByteBufferFromPool() method to ByteBuffer.h. - The HashtableEntry class now stores references to other HashtableEntries as uint32 slot indices rather than pointers, so that its memory footprint doesn't increase on 64-bit systems. - Added a GetRawArrayPointer() method to the Queue class to allow direct/low-level access to the Queue's items array. - UnparseArgs(const Queue &) now takes optional startIdx and afterEndIdx arguments. o 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--(). o Rewrote/simplified the MessageFieldNameIterator class: Removed the HasMoreFieldNames(), GetNextFieldName() and PeekNextFieldName() methods. The only methods remaining are HasData(), GetFieldName(), operator++, and operator--. o The String, Point and Rect classes no longer derive from Flattenable, and no longer have any virtual methods. o 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. 5.11 Released 11/23/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(). o Rewrote the Windows implementation of the Mutex class to use critical sections rather than locking a Windows Mutex directly, for better performance. o 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. o 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. 5.10 Released 10/12/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. o Changed the MUSCLE_VERSION macro in support/MuscleSupport.h from hexadecimal to decimal, so it can be more readable. o FileDataIO ctor's argument now defaults to NULL. o 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. o 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. o 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. o 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. o Added a PrintStackTrace() comment to SysLog.cpp for easy copy-and-paste to third party code when necessary. o 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. o 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. 5.00 Released 9/16/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. o Removed CStringHashFunc() and CStringHashFunc64() functions; any code that was previously using those should call CalculateHashCode(s,strlen(s)) instead. o 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. o All Hashtable sorting is now done via CompareFunctors instead of via function pointers. o 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. o Remove the Compare*() callback functions from MuscleSupport.h because they are no longer needed (use functors instead) o Made PulseNode::InvalidatePulseTime() public instead of protected. o 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. o 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. o Removed UNLESS() macro, since it was never used and was bad style. o FindFirstSessionOfType() and FindSessionsOfType() template methods now take as their template argument, not o 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. 4.63 Released 7/17/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 "*". o Renamed DataNode::CountChildren() to DataNode::GetNumChildren(). o Renamed DataNode::SetMaxKnownChildID() to DataNode::SetMaxKnownChildIDHint(). o Renamed Message::CountNames() to Message::GetNumNames(). o Rewrote the static internal function AdjustValue() in SharedUsageLimitAllocator.cpp to give more informative error output. o Removed Message::GetConstPointer() since you can use GetPointer() to do the same thing (by assigning a const pointer to the result). o 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. 4.62 Released 6/17/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. o Added testthread.cpp back in to the test/Makefile. o Modified testthread.cpp to test the ThreadLocalStorage class also. o Reorganized the ObjectPool.h class implementation. o 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. 4.61 Released 5/22/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". o Removed the "catchsignals" support from muscledMain()'s setup code, since that support is now part of HandleStandardDaemonArgs() instead. 4.60 Released 5/15/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. o The arguments to the Log() method in the LogCallback API are now consolidated into a single LogCallbackArgs object, for efficiency and cleaner code. o The GetStandardLogLinePreamble() function now takes a single LogCallbackArgs argument instead of separate args also. o 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. o Rewrote portablereflectclient to use StdinDataIO instead of accessing stdin directly. This allows it to work correctly under Windows, and simplifies the code. o 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. o Suppressed a warning in zip.c o 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. 4.51 Released 3/19/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. - Added Monni's 64-bit x86 byte-swap routine to MuscleX86SwapInt64(). o RemoveEscapeChars() and EscapeRegexTokens() now take a const String and return a String. This makes them easier to use in nested function calls. o Repackaged the com.lcs.* Java hierarchy as com.meyer.*, to reflect my company's name change. o 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. 4.50 Released 1/28/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. o Rolled in Mika Lindqvist's Haiku-compatibility patches. o Renamed the standard "log" and "display" keywords to "filelevel" and "displaylevel", respectively. o Removed the OutOfMemoryCallback and FunctionOutOfMemoryCallback classes and replaced them with more general-purpose GenericCallback and FunctionGenericCallback classes. o Tweaked a call to FD_ISSET() in system/Thread.cpp in order to avoid a compiler warning under g++ 4.3.1 o Tweaked the _PLOCKimp and _PUNLOCKimp debug functions to compile properly in 64-bit environments. o Updated the Message.h Doxygen documentation with some more descriptive parameter names. o hexterm no longer disables multicast-to-self when sending multicast UDP packets. o Removed DebugTimer.cpp; that code has moved to SetupSystem.cpp. o 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) 4.41 Released 11/17/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. 4.40 Released 10/16/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. o Renamed GenericRef to RefCountableRef, for consistency. o Renamed PolicyRef to AbstractSessionIOPolicyRef, for consistency. o Renamed Ref::SetFromGeneric() and Ref::GetGeneric() to Ref::SetFromRefCountableRef() and Ref::GetRefCountableRef(), respectively, for consistency. o testrefcount now runs a 10-second test of reference-counts in a heavily multithreaded environment, to ensure that they are thread safe. o 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. 4.30 Released 9/18/2008 *** WARNING - THIS RELEASE CHANGES THE PulseNode API IN a NON *** *** BACKWARDS COMPATIBLE WAY. BE SURE TO READ THE ENTRY ABOUT *** *** PulseNode BELOW AND UPDATE YOUR CODE TO MATCH THE NEW API. *** - 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. o 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. o Fixed some compiler warnings under gcc (thanks to Monni for pointing these out) o 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. 4.28 Released 8/26/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(). o Made the AbstractReflectSession::EndSession() method virtual. o 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) 4.27 Released 7/24/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 now print to places other than stdout if you prefer. - The testchildprocess test program now has you specify the number of child process instances to run. That makes it easier to test what happens when many child processes are launched in parallel. o Merged in some more of Mika Lindqvist's Haiku compatibility tweaks. o Hashtable::GetByDefault() with one parameter now returns its result by reference instead of by value. o The Hashtable and Queue classes now keep default instances of their user types, to avoid having to construct temporary default objects when resetting objects to their default state. * PrintStackTrace() now prints appropriate error messages if it fails, instead of just failing siliently. * Fixed a syntax error in Hashtable::Remove(const Hashtable &) * Hashtable::Clear() now handles re-entrancy (from the templatized classes' assignment operators) correctly. 4.26 Released 6/5/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. 4.25 Released 5/14/2008 - Added a DECLARE_HASHTABLE_KEY_CLASS macro that expands to the boilerplate template code necessary to use the specified class as a key in a Hashtable. - Added a DECLARE_HASHTABLE_KEY_CLASS_IN_NAMESPACE macro which is the same as DECLARE_HASHTABLE_KEY_CLASS except it works from within namespaces other than muscle. - Added PutIfNotAlreadyPresent() convenience methods to the Hashtable class. - Added CopyFrom() method to the Queue and Hashtable classes. These work the same as the assignment operator, except that they return a status_t result code. - Added a SetFilter() method to the PathMatcherEntry class. o Cleaned up the setsockopt() and getsockopt() calls inside NetworkUtilityFunctions.cpp to be more portable. * ExplandLocalhostAddress() is now more careful not to expand (localhostIP) back into (localhostIP), even if that is the first IP address listed in the interfaces list. * Fixed a bug in the QueryFilter subscriptions feature -- after replacing a subscription's existing QueryFilter, the old QueryFilter would continue to be used instead of the new one. 4.24 Released 4/28/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(). o Made AbstractReflectSession::IsConnectingAsync() public. o 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. 4.23 Released 3/26/2008 - Added an UnparseArgs() function to MiscUtilityFunctions.{cpp,h}. This function takes a parsed Message and turns it back into a String. - Added an InsertItemsAt() method to the Queue class. - Added an (includeLocalhost) boolean argument to GetNetworkInterfaceInfos(). - Made ServerComponent::SetOwner() and ServerComponent::GetOwner() public, as it is necessary for classes other than ReflectServer to access that value in order to properly support the facade pattern within ReflectSessionFactory objects. - Added a ProxySessionFactory class to support facade-style ReflectSessionFactories better. - Added an optional ITraversalPruner argument to both StorageReflectSession::SaveNodeTreeToMessage() and StorageReflectSession::RestoreNodeTreeFromMessage(). This argument lets the caller specify a callback argument that can direct the traversal based on custom logic, if necessary. o Replaced StorageReflectSession::CloneDataNodeSubtree()'s rather clunky MessageReplaceFunc and void-pointer filtering mechanism with the nicer and more powerful ITraversalPruner filtering mechanism. * Fixed a bug in FilterSessionFactory and SharedFilterSessionFactory where an assertion failure would occur if the "slave" factory attempted to call GetSessions(), etc. * SharedFilterSessionFactory's IP-address checking was broken. Fixed. * AbstractReflectSession::GetPort() was broken and would always return 0. Fixed. v4.22 Released 3/4/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. o 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. o 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. v4.21 Released 1/22/2008 - Optimized Hashtable::GetOrPut(), CopyToTable(), MoveToTable(), Put(), and Remove() to be more efficient. o Updated the muscle.dox Doxygen file to reflect changes to newer versions of Doxygen * Hashtable::Put() and Hashtable::Remove() now do the right thing if they are passed (*this) as an argument. * Fixed a nasty bug in the ObjectPool destructor that would cause it to go into an infinite loop, calling delete on the same array over and over again. * Filled in and fixed up the Doxygen comments to the point where Doxygen no longer gives any warnings when generating the autodocs. o Updated all copyright notice headers to read 2000-2008 Meyer Sound. v4.20 Released 12/31/2007 - Added an optional set of multicast networking API calls to util/NetworkUtilityFunctions.h. Define the constant MUSCLE_ENABLE_MULTICAST_API to make them available. - hexterm will now automatically use multicast UDP if you specify a multicast UDP address as an argument. For example, ./hexterm udp=239.255.1.2:4001 - Added SetSourceExclusionID() and GetSourceExclusionID() methods to the PacketTunnelIOGateway class, to enable more efficient filtering of looped-back broadcast/multicast packets that you sent out and don't want to see back again. - Added a ParseHexBytes() function to MiscUtilityFunctions.{cpp,h} - Under Linux, HandleStandardDaemonArgs() now takes a new argument "debugcrashes" which will cause a signal handler to be installed that will catch SIGSEGV, SIGBUS, SIGILL, SIGABRT, and SIGFPE, and print a stack trace to stdout before exiting. - Added RemoveFirst() and RemoveLast() convenience methods to the Hashtable class (handy when using the Hashtable as a keyed FIFO or LRU) o Moved the PrintHexBytes() function into system/SetupSystem.cpp so that you don't have to link in MiscUtilityFunctions.cpp just to use it. * Tweaked FinalizeAsyncConnect() to work properly under BeOS. * Improved the BeOS/BONE detection -- Makefile support no longer required. v4.11 Released 12/11/2007 - GetHumanReadableTimeString() and ParseHumanReadableTimeString() now handle the uint64 value MUSCLE_TIME_NEVER as a special case, by translating it into the string "(never)" (and back). - Added a CalculateChecksumForUint64(), CalculateChecksumForFloat(), and CalculateChecksumForDouble() convenience functions to MuscleSupport.h - Added a FindFirstMatchingNode() method to the DataNode class, which can be used to efficiently look up a descendant node based on a relative or absolute path, with or without wildcard matching characters. - Added a GetRootNode() convenience method to the DataNode class which returns the root node of the DataNode tree. - Added SetAllowMiscIncomingData() and GetAllowMiscIncomingData() methods to the PacketTunnelIOGateway class, so that a UDP socket controlled by a PacketTunnelIOGateway can optional receive individual (non-packetized) arbitrary UDP packets as well as the packetized kind. This mode is disabled by default. - Added a Normalize() method to the Queue class that can be used to ensure that the Queue's contents are layed out contiguously in memory (like a C array). - Added a AddNewDormantConnectSession() method to the ReflectServer and ServerComponent classes. This method is the same as AddNewConnectSession() except that the added session will not start a TCP connection immediately; instead it will hang out and wait for you to call Reconnect() on it. - Added a PrintHexBytes() convenience/debugging function to MiscUtilityFunctions.h o Removed the (countFieldOrder) argument from the Message::CalculateChecksum() method. o Changed instances of ((uint32)-1) literals to the more proper MUSCLE_NO_LIMIT constant in a number of places. o Rewrote StorageReflectSession::GetDataNode() as a simple inline call-through to FindFirstMatchingNode(), which means that GetDataNode() now supports wildcard matching. o GetHumanReadableTimeValues() now returns B_ERROR if you pass it MUSCLE_TIME_NEVER as a time value (since there is no good numeric way to represent infinity). o DataNode::PrintToStream() and Message::PrintToStream() no longer print this-pointer values in their debug output, because doing so makes it harder to diff state dumps from different processes. o AbstractReflectSession::Reconnect() and SetAutoReconnectDelay() can now be used in conjunction with sessions that were not added with AddNewConnectSession() also. In this context, they will "reconnect" the session by destroying its gateway and DataIO objects and creating new ones by calling CreateDefaultSocket() and CreateDataIO(). * system/AcceptSocketsThread.h was missing a necessary #include line. Thanks to Mika Lindqvist for reporting this. * Fixed a bug in DataNode::InsertOrderedChild() that could cause the inserted child's node name not to be unique in some circumstances. * DataNode::PutChild() now takes a (const DataNodeRef &) instead of a (DataNodeRef &). * Removed the index-order multiplication from most implementations of CalculateChecksum(), since including an index-multiplier in the checksum makes it inefficient to update a running checksum tally when inserting or removing items in the list. * The Thread class now closes the internal thread's side of the inter-thread socket connection when the internal thread hook function exits. That way the main thread can be notified that the child thread has gone away (the main thread's socket will select() ready-for-read because of the socket close) v4.10 Released 10/30/2007 - Added Bryan Varner's MicroMUSCLE port to the archive, in the new java_j2me folder. MicroMUSCLE is a fork of the MUSCLE Java code that is compatible with the J2ME edition of Java being used on modern cell phones, etc. Unlike the standard MUSCLE Java API, this version doesn't require Java 1.4.x APIs to be supported. - Added a GetNumberOfProcessors() function to the SystemInfo.h API. You can call this to find out how many CPU cores the computer you are running on has. - Made LockLog() and UnlockLog() part of the public MUSCLE syslog API, in case you want to use the log mutex in your own critical section. - Added a CalculateChecksum() utility function to MuscleSupport.h - Added CalculateChecksum() functions to the String, ByteBuffer, Point, Rect, Message, and DataNode classes. These methods compute a quick checksum on the object's contents which can then be used for sanity-checking later on. - Added a PrintToStream() method to the DataNode class for quick recursive dumping of database subtrees to stdout. - Message::PrintToStream() and Message::ToString() now include the checksum value of the Message. - Added IsInBatch() and IsOutermost() methods to the NestCount class, for convenience and code clarity. (Before they were only present in the NestCountGuard class) - Added a KillChildProcess() method to the ChildProcessDataIO class, for times when you need the child process dead right away but you want to keep the socket to it open (so that it will error out as if the child process died of its own accord). - Added IsDescendantOf() and IsAncestorOf() convenience methods to the DataNode class. - Added a StringCompareFunc() override to String.h that takes (const String *)'s as arguments. Useful when you want to save space in a Hashtable of string-keyed, ref-counted objects, by changing the key-type to a pointer to a string that is held in the referenced value-objects. - Added a Message::FindString() method override that sets a pointer-to-a-String, so that you can access the underlying String object without having to copy it. - Added a ServerComponent::GetSession() override that takes a uint32 for the session ID argument. - Added convenience versions of StringMatcher::Match() and HasRegexTokens() that take a String argument instead of a (const char *). - Added a GetEmptyMessageRef() convenience function to Message.h. It's like GetEmptyMessage() except it returns a (const MessageRef &) instead of a (const Message &). - The StdinDataIO class now works as expected under Windows. In particular, it implements some backstage trickery so that you can use its GetSelectSocket() return value in select() even though Windows doesn't support doing that. o Removed GetBlankMessage() from the StorageReflectSession API. Use GetEmptyMessageRef() instead. o DataNode::GetData() now returns a (const MessageRef &) instead of a MessageRef. o The GetSessions() method now returns a Hashtable instead of a HashtableIterator. o The GetNumSessions() method has been removed; use GetSessions().GetNumItems() instead. o The GetFactories() method now returns a Hashtable instead of a HashtableIterator. o The GetNumFactories() method has been removed; use GetFactories().GetNumItems() instead. o Tweaked some of the code to avoid new warnings in gcc 4.1.x o The SetDataNode(), FindMatchingSessions(), CloneDataNodeSubtree(), NotifySubscribersThatIndexNodeChanged(), NodeIndexChanged(), GetNewDataNode(), and JettisonOutgoingSubtrees() methods in the StorageReflectSession class not take String arguments instead of (const char *) o The InsertOrderedChild(), ReorderChild(), HasChild(), GetChild(), and RemoveChild() in the DataNode class now all take String arguments instead of (const char *). o DataNode::GetPathClause() now returns a (const String *) instead of a (const char *). o FilterSessionFactory Put*Pattern() and Remove*Pattern() methods now take (const String &) arguments instead of (const char *). o The StdinDataIO class no longer derives from the FileDescriptorDataIO class. This way it is possible to use StdinDataIO under Windows (which doesn't support file descriptors). o Moved the StdinDataIO code into its own separate StdinDataIO.cpp file, to better hide the ugly Windows implementation. * Fixed a VC++ compatibility issue in ObjectPool.h. Thanks to Mika Lindqvist for reporting this problem. * Fixed a bug in AcceptSocketsThread.cpp. Thanks to Mika Lindqvist for reporting this problem also. * Fixed a HANDLE leak in the Windows implementation of the RS232DataIO and ChildProcessDataIO classes. v4.00 Released 10/03/2007 *** WARNING - THIS RELEASE RATIONALIZES SEVERAL APIS AND THUS *** *** BREAKS SOURCE COMPATIBILITY WITH MOST OLD CODE. DON'T *** *** UPGRADE TO THIS RELEASE UNLESS YOU ARE WILLING TO UPDATE *** *** YOUR CODEBASE TO MATCH. *** - Added a SanitySetupSystem class to the CompleteSetupSystem object. SanitySetupSystem just does some very quick tests on the typedef sizes (int16, int32, etc) and endian-ness of the compiled code to make sure that the code's build settings are compatible with the run-time environment. If any of the tests fail, it prints out a stern error message and aborts the program. - Added convenience methods for AddFlat(), PrependFlat(), FindFlat(), and ReplaceFlat() to the Message class that take a ByteBufferRef as an argument. That way you can deal with Messages and ByteBufferRefs without always having to look up how to cast a ByteBufferRef to a FlatCountableRef and back. - Added HasChars() and IsEmpty() convenience methods to the String class, for consistency with the other container classes. - Rewrote the ObjectPool class to do its object allocations in 8 kilobyte "slabs" rather than one at a time. This cuts down on the number of calls to new/delete by an order of magnitude. - Added a -DMUSCLE_POOL_SLAB_SIZE build option in case you want the ObjectPools to use a different slab size. This value is specified in bytes. - Added an ExitWithoutCleanup() function to MiscUtilityFunctions.{cpp,h}, which is equivalent to _exit(). This wrapper function exists because I suspect _exit() may not be entirely portable. - Added a "testpool" program to the tests folder to measure the relative efficiency of various object-allocation techniques. - AbstractReflectSession::GetSessionIDString() now returns a (const String &) instead of a (const char *). - Added a GetSessionID() accessor to AbstractReflectSession. - Added a CreateDefaultSocket() method to the AbstractReflectSession class. This method is called when AddNewSession() is passed a null SocketRef, and if implemented to return a non-NULL SocketRef, can be used to provide a default socket for the session. - Added a StdinDataIO class that can be used to do non-blocking-I/O on stdin without breaking the blocking-I/O functionality of stdout. o Renamed the SocketHolderRef class to Socket. o Added the a SocketRef class (which subclasses Ref) o All MUSCLE functions that previously dealt with sockets as integer file descriptors now use the new SocketRef type instead. This way there is no chance of leaking or double-freeing allocated sockets. o Removed the CloseSocket() function from the API, since it is no longer necessary. * Changed the static casts in StorageReflectSession.cpp to dynamic_cast<>, so that ReflectServers holding some sessions derived from StorageReflectSession and some derived directly from AbstractReflectSession will now work without crashing. o Removed GetDataIORef() and GetGatewayRef(), and changed GetDataIO() and GetGateway() to return references to Ref objects instead of pointers to objects. o AbstractReflectSession::CreateDataIO() now takes a (const SocketRef &) argument instead of an int, and now returns a DataIORef instead of a (DataIO *) o AbstractReflectSession::CreateGateway() now returns an AbstractMessageIOGatewayRef instead of a (AbstractMessageIOGateway *) o ReflectSessionFactory::CreateSession() now returns an AbstractReflectSessionRef instead of a (AbstractReflectSession *) o StorageReflectSession::GetNewDataNode() now returns a DataNodeRef instead of a (DataNode *). This way any chance of a memory leak is avoided. o StorageReflectSession::ReleaseDataNode() has been removed since it is no longer necessary. o RefCountable's copy constructor no longer copies the _manager pointer, since items allocated in one ObjectPool can no longer be freed by a different ObjectPool. o MessageTransceiverThread::CreateSupervisorSession() now returns a ThreadSupervisorSessionRef instead of a (ThreadSupervisorSession *) o MessageTransceiverThread::CreateDefaultWorkerSession() now returns a ThreadWorkerSessionRef instead of a (AbstractReflectSession *) o MessageTransceiverThread::CreateDefaultSessionFactory() now returns a ThreadWorkerSessionFactoryRef() instead of a (ReflectSessionFactory *). o ThreadWorkerSessionFactory::CreateThreadWorkerSession() now returns a ThreadWorkerSessionRef instead of a (AbstractReflectSessionRef *). o The MessageTransceiverThread::AddNew*Session() family of methods now take a (const ThreadWorkerSessionRef &) argument instead of (const AbstractReflectSessionRef &). o The MessageTransceiverThread::PutAcceptFactory() family of methods now take a ThreadWorkerSessionFactoryRef argument instead of a ReflectSessionFactory. o MessageTransceiverThread::CreateReflectServer() now returns a ReflectServerRef instead of a (ReflectServer *). o The ReflectServer class now derives from RefCountable and has an associated ReflectServerRef typedef. o Removed the SetOkayToClose*() methods from the MessageTransceiverThread class, as they are no longer necessary. * BecomeDaemonProcess() now calls ExitWithoutCleanup() instead of exit(), to avoid crashing the parent process in the globals-cleanup phase (since the CompleteSetupSystem object destructor never gets a chance to run). * Replaced all calls to exit() with calls to ExitWithoutCleanup(). * Tweaked FileDescriptorDataIO to compile correctly on 64-bit systems. * Fixed typedefs of int32/uint32 for the PPC64 platform. * Fixed typedef of muscle_socklen_t on PPC64 * ZipFileUtilityFunctions.cpp was calling newnothrow to allocate an array. Changed it to call newnothrow_array instead. * RefCount::SetFromGeneric() would return B_NO_ERROR if you tried to call SetFromGeneric(NullRef()), but it wouldn't actually change the state of the Ref that you called it on. It now sets the state to NULL in that case. * AtomicCounter.h now uses the public QAtomicInt API when compiled with Qt 4.4.0 or higher. (When compiling with Qt 4.0.0 through 4.3.x, it will still use the old private atomic API) * Applied some tweaks to MuscleSupport.h for better MacOS/X Leopard compatibility. * Tweaked SharedMemory.h to compile on MacOS/X Leopard. v3.40 Released 9/6/2007 - Added experimental IPv6 support. To use MUSCLE with IPv6, compile your code with the -DMUSCLE_USE_IPV6 flag. The new typedef ip_address will then be compiled as a 128-bit datatype (the new ip_address class) instead of being typedef'd to uint32. - Added a new PacketTunnelIOGateway class that is useful for "tunneling" arbitrarily large Messages over a packet-based protocol with a smaller maximum packet size (e.g. UDP). The PacketTunnelIOGateway class will packetize large Messages and reconstruct them from the fragments at the other end. - Added SetAutoReconnectDelay() and GetAutoReconnectDelay() methods to the AbstractReflectSession class. You can use these to easily configure your AbstractReflectSession to automatically reconnect itself after its connection to the server has been broken. - Added a new, optional (autoReconnectDelay) to all the AddNewConnectSession() methods in MessageTransceiverThread, QMessageTransceiverTherad, ServerComponent, and ReflectServer. If specified, this argument will cause SetAutoReconnectDelay() to be called on the new session. - Added a new PacketizedDataIO class that can be used to "wrap" a streaming DataIO class (e.g. TCPSocketDataIO) and make it act more like a packet-style DataIO class (e.g. UDPSocketDataIO). - Accept() now has an optional second argument, which will return the IP address of the interface that a connection was accepted on. - Added a new IPAddressAndPort class which is handy for encapsulating an IP address and port number together in the same object. - PutAcceptFactory() and RemoveAcceptFactory() now accept optional local interface IP address arguments so that you can specify that connections to the server should only be accepted on a certain interface, if that's what you want. - PutAcceptFactory() now accepts an optional (retPort) argument which you can use to find out which port the factory was installed on. - PutAcceptFactory() now puts its connection-accepting socket into non-blocking mode so that the server can't ever block inside Accept(). - Added a GetLocalInterface() method to the ReflectSessionFactory class so you can see which interface(s) that factory is associated with. - Added some more convenience methods to the Hashtable class: versions of GetNextKey(), PeekNextKey(), GetNextValue(), and PeekNextValue() that take a pointer-reference as their sole argument. - ReflectSessionFactory objects are now auto-assigned a globally unique ID number when they are created. This number can be accessed by calling ReflectSessionFactory::GetFactoryID(). - Added a simple portscan utility (called "portscan") to the tests folder. - Added a GetChildProcessID() method to the ChildProcessDataIO class, which returns the child process's process ID (pid). - Added a ByteBufferDataIO class that lets you read/write ByteBuffer objects using the DataIO interface (as if they were files). - Added GetFirstFieldNameString() and GetLastFieldNameString() convenience methods to the Message class, so that you don't need to set up a MessageFieldNameIterator just to get a single field out of the Message. - Added a GetSourceOfLastReadPacket() method to the UDPSocketDataIO class, so that you can find out after a Read() call where the data you just read came from. - Added a SetSendDestination() method to the UDPSocketDataIO class, so that you can have Write() call sendto() instead of send() if you prefer. - Added a GetSendDestination() method to the UDPSocketDataIO class. - Added a testpacketio test to the tests folder, to unit-test the PacketizedDataIO class. - Added a testpackettunnel test to the tests folder, to unit-test the PacketTunnelIOGateway class. - Added a NestCount convenience class to the util folder. This simple class handles some of the drudge work associated with tracking recursion levels of recursive function calls. - Added a Reposition() method to the Hashtable class that can be used to manually update the position of an auto-sorted-by-value entry that has been modified in-place. - Added MoveToTable() and CopyToTable() convenience methods to the Hashtable class. - Made some minor optimizations to the auto-sort-by-value code in the Hashtable class. o Removed the MemoryBufferDataIO class, since it was not very useful or well designed. o Changed the MessageTransceiverThread class's GetNextEventFromInternalThread() method so that it passes back the ReflectSessionFactory's ID (as a uint32) instead of its port number (as a uint16). This was done because port numbers are no longer unique identifiers for session factories. o Changed the ReflectSessionFactory::CreateSession() method to take different arguments (note that this will break old code that defined its own ReflectSessionFactory subclasses! That code will need to be updated to use the new arguments) o The NetworkInterfaceInfo class's GetName() and GetDescription() methods now return references to String objects, instead of character pointers. o Moved the declaration of Inet_NtoA() from MiscUtilityFunctions.h to NetworkUtilityFunctions.h. o Removed the GetLocalIPAddress() function from NetworkUtilityFunctions.{cpp,h}, as it is redundant with (and less useful than) the new GetNetworkInterfaceInfos() function. o Removed the GetPort() method from the ReflectSessionFactory class, since factories are no longer necessarily associated with exactly one port number. * The final argument to the CreateAcceptingSocket() function in NetworkUtilityFunctions.h was documented incorrectly. It lets you specify the IP address of a local interface, not a client's IP address. * The final argument to the SetPort() function in AcceptSocketsThread.h was documented incorrectly. It lets you specify the IP address of a local interface, not a client's IP address. * Fixed a bug in ReflectServer's ReflectSessionFactory design that caused muscled not to work correctly if you told it to listen to more than one port at once. * Added an #ifdef to NetworkUtilityFunctions.cpp so that it will compile cleanly on BeOS/R5.0.3 * HashtableIterator::GetValue() was returning a const reference. Changed it to return a non-const reference, since there's no reason why you shouldn't be able to modify the returned object. * Fixed a bug where calling PutAcceptFactory() with the port argument set to zero would cause all already attached accept-factories to be removed. * Fixed a minor bug in the ReflectServer event loop, where the fd_sets would be inspected after select() returned -1/EINTR. This could cause spurious (albeit generally harmless) read-ready or write-ready events to be detected. * The assignment operator, equality operator, ContainsValue(), and the batch Put() and Remove() methods in the Hashtable class now specify the HTIT_FLAG_NOREGISTER flag in their HashtableIterator objects, for better thread safety. v3.34 Released 7/12/2007 - Optimized CreateConnectedSocketPair() by having it use the UNIX socketpair(AF_UNIX) function on systems that support that call. o Removed the optional (useNagles) argument from the CreateConnectedSocketPair() function, since there is little or no point in using Nagles algorithm for sockets within the same process. (if you really needed it for some reason, you could still call SetSocketNaglesAlgorithmEnabled() manually on the resulting sockets afterwards) o test/cvscopy.cpp is now test/svncopy.cpp, since I don't use CVS anymore. * Thread::WaitForNextMessageAux() wasn't handling file descriptors properly when called with a wakeupTime less than or equal to the current time. Fixed. o Added a testpulsenode.cpp file to the tests folder, to test the reliability and scalability of the PulseNode timed-event-callback implementation. * Fixed some valgrind hits in NetworkUtilityFunctions.cpp by having the code check the sin_family of sockaddr structs before reading any IPv4-specific fields. * QMuscleSupport.h wouldn't compile under Qt 3.x. Fixed. * Added Mika Lindqvist's patches to get QMuscleSupport.h to compile under older versions of Microsoft Visual C++. * The SharedUsageLimitProxyMemoryAllocator class was not always freeing all of the cached memory during large free operations, which could result in the process-memory-cache getting too large. Fixed. * Fixed a bug in the PulseNode class's linked list code that could cause PulseChildren to not have their Pulse() methods called at the proper times. * Merged in Bryan Varner's patch to the MessageTransceiverThread Java class so that spurious connect-succeeded tags are no longer sent by the I/O thread to the main thread. v3.33 Released 6/6/2007 - Added a MultiDataIO class, for convenient writing of mirrored files, etc. - Added a qtsupport/QMuscleSupport.h header file to contain Qt-specific utility/helper code. Currently this file contains only a QString specialization of the HashFunctor template, to allow QStrings to be used as keys in a Hashtable. * SetupSystem.cpp builds again under BeOS (worked around BeOS's non-standard gmtime_r() call) * Merged in Lior Okman's patch to the Java client code to fix a bug where partially received Messages might get dropped, causing a TCP disconnect. * Added a loop around the Unix implementation of SharedMemory::AdjustSemaphore()'s call to semop(), so that if semop returns EINTR, the call is retried. v3.32 Released 5/2/2007 - Added a new class, SharedFilterSessionFactory, which looks at the contents of a shared memory region to decide which client IP address(es) to allow to connect to the server. - Added a IsIPAddress(const char *) convenience method to NetworkUtilityFunctions.{cpp,h}. This method returns true iff its argument is a string representing an IP address in human-readable ASCII format. - Added a new function GetNetworkInterfaceInfos() to NetworkUtilityFunctions.{cpp,h}. This function returns a list of NetworkInterfaceInfo objects describing the various network interfaces currently available on the host machine. - test/testnetutil.cpp Now tests GetNetworkInterfaceInfos() by calling it and printing out the results. - Added a new argument (emitEndMessageBatchIfNecessary) to the QMessageTransceiverHandler::Reset() and QMessageTransceiverThread::UnregisterHandler() methods, so that if these methods are called while in the middle of a receiving-Messages batch, the un-registering of the handler will no longer cause an imbalance between the number of BeginMessageBatch() and EndMessageBatch() signals that get emitted by the handler. (You can override this behavior by passing in false for the new argument) - The muscle/java/build.xml file now builds JavaDocs too. o AbstractReflectSession::GetHostName() now returns a (const String &) instead of a (const char *). * Fixed a bug in SharedMemory::DeleteArea() that was preventing the shared memory area's semaphore from being deleted. * Rewrote the linked-list handling code in the QMessageTransceiverThread class to use a doubly-linked-list. This fixes a bug where the previous singly-linked-list would occasionally not get updated properly, resulting in the failure to emit EndMessageBatch signals in some circumstances. * The GlobalMemoryAllocator class now calls AboutToFree() if AboutToAllocate() succeeded but malloc() or realloc() failed. That way AboutToFree() can undo AboutToAllocate()'s side effects in the usual fashion. * The SharedUsageLimitProxyMemoryAllocator class would deduct a buffer's memory size from the tally twice in the event of a memory failure. Fixed. * The SharedUsageLimitProxyMemoryAllocator class now detects when a program tries to reduce its memory usage counter to less than zero, and clamps the counter to zero instead of letting it wrap around to the 4 gigabyte range. * The GlobalMemoryAllocator class now calls SetAllocationHasFailed() on the MemoryAllocator object only if the second try to allocate memory has also failed. That way, if the first try fails, but the MemoryAllocator's AllocationFailed() method is able to free up some space to make the second try succeed, program operation can proceed without any further disruption. * ProxyMemoryAllocator::AllocationFailed() no longer calls SetAllocationHasFailed(true) on its slave allocator. That call is to be made solely by ProxyMemoryAllocator::SetAllocationHasFailed(), instead. * AutoCleanupProxyMemoryAllocator::AllocationFailed() now calls up to its parent class as well as doing its regular OutOfMemory() callbacks. * Cleaned up the JavaDoc comments so that they now build without any warnings from the javadoc utility. * The POSIX implementation of GetCurrentTime64() wasn't handling Daylight Savings Time properly, which meant its result would be off by an hour for part of the year. Fixed. * Changed some calls to gmtime() and localtime() to gmtime_r() and localtime_r() respectively, to make them thread-safe. v3.31 Released 3/14/2007 - The AtomicCounter API is now aware of Qt 4's atomic counter API, and will use that as its implementation in Qt-enabled programs compiled on systems where MUSCLE's own inline-assembly support isn't available. - hexterm will now send ASCII bytes if you prefix them with a slash (e.g. "/0 /1 /2" sends 0x30, 0x31, 0x32) - Added a Hashtable::IndexOfValue() function that lets you find the index of the first (or last) value of a given type in a Hashtable. (with O(N) search time) - Added implementations of the GetByteBufferFromPool() and GetMessageFromPool() functions that take a user-specified ObjectPool instead of using a default object pool. - Added support for a new compiler flag, MUSCLE_64_BIT_PLATFORM, which can be defined in your Makefile if you are on a 64-bit platform that isn't autodetected inside of MuscleSupport. - Added INT32_FORMAT_SPEC and UINT32_FORMAT_SPEC macros so that printf() statements can be made less architecture-specific. - Added a section to the test/testtypdefs.cpp test that checks to make sure the *_FORMAT_SPEC macros are working correctly on the current platform. - DataNode::GetChildIterator() now takes an optional flags parameter that is passed on to the HashtableIterator constructor. - Added a DataNode::HasChildren() convenience method. o Made the String class's destructor inline. * SetupSystem.cpp wouldn't compile on 64-bit systems when using Mutexes to implement atomic operations. Fixed. * Merged in Lior Okman's patch to the Java client code that sets the socket's send and receive buffers to 128KB. * Merged in Lior Okman's patch to the Java client code to fix an occasional busy-loop that could occur when receiving very large (>400KB) Message objects. * Merged in Nathan Whitehorn's patch to the FreeBSD #ifdef's in NetworkUtilityFunctions.cpp. * Fixed a bug in MemMem() that where an incorrect return value would be returned when both buffers were the same size. * Fixed a bug in RawQueryFilter::SetFromArchive() that could cause a crash. * Some of muscle's text output would be wrong on 64-bit platforms. Fixed by changing all printf()'s to use the new INT32_FORMAT_SPEC and UINT32_FORMAT_SPEC macros when appropriate. * Fixed a bug in the Makefiles so that g++ now compiles all code with all warnings enabled (except the multi-char constants warning). * Went through the test files and fixed the minor problems that were causing them to generate compiler warnings with -Wall enabled. * hexterm now prints out an error message when it aborts due to an invalid return code from Read() or Write(). v3.30 Released 1/16/2007 ***NOTE*** In this release, the byte-swapping functions for floating point and double-precision floating point operations have been renamed. If your code handles floating-point byte swapping itself, you will need to update your code before it will compile. See the FLOAT_TROUBLE and DOUBLE_TROUBLE comments in support/MuscleSupport.h for details about this issue. - Added a QMessageTransceiverHandler helper class to QMessageTransceiverThread.{cpp,h}. This class handles the multiplexing and demultiplexing of multiple session objects inside a single QMessageTransceiverThread object, so that Qt-based programs that use a N:1 session-to-thread model will be easier to write and maintain. - Added a QMessageTransceiverThreadPool helper class to QMessageTransceiverThread.{cpp,h}. This class manages the automatic creation of QMessageTransceiverThreads when QMessageTransceiverHandlers are set up, so that an N:1 session-to-thread model can be implemented automatically in Qt-based programs. - Rewrote hexterm's output routine to be more useful; it now outputs both ASCII and hex data, in a format similar to that used by od. - Added chatclient.cpp to the tests folder. chatclient.cpp is a simple command-line BeShare compatible chat client (previously distributed separately as "Clyde") - Added a minichatclient.c to the tests folder. minichatclient.c is a C-only implementation of chatclient.cpp, just to show how it can be done using only the MiniMessage and MiniMessageGateway APIs. - Added a MemMem() function to MiscUtilityFunctions.{cpp,h}. MemMem() is similar to strstr(), except that instead of operating on NUL-terminated strings, it operates on binary data. - Rewrote the PulseNode class to be more efficient when many children are present -- PulseNode now stores its children in ordered linked lists rather than in a Hashtable, and it no longer needs to iterate over all children in order to recalculate the next event time. - Merged in Lior Okman's enhancement to the Java API: StringBuffer is now used in toString() methods, instead of concatenating strings directly. - Merged in Lior Okman's enhancement to the Java API: Faster ByteBuffer operations are now used to fill in arrays, instead of looping over the arrays and manually setting the values. - Merged in Lior Okman's enhancement to the Java API: Use List instead of Vector and HashMap instead of HashTable. This is to lose the extra unneeded synchronization point that exists in these old and deprecated (as of Java 1.2) classes. Since ByteBuffer requires at least JDK 1.4 anyway, there is no need to use the older API. - Merged in Lior Okman's enhancement to the Java API: Use Iterator instead of Enumeration - same reason as above. Note that this change will break compatibility with old Java code that calls Message.fieldNames() -- it will need to be updated to use an Iterator instead of an Enumeration. - Merged in Lior Okman's enhancement to the Java API: Changed the implementation of Queue.removeAllElements() to a more efficient implementation. - Merged in Lior Okman's enhancement to the Java API: Modified the ThreadPool to use a ThreadGroup and provide thread names. This makes the class more profiler-friendly. - Merged in Lior Okman's enhancement to the Java API: Message.flatten() is faster now, because it doesn't call flattenedSize() as much anymore. - Merged in Lior Okman's patch that adds a setOutgoingEncoding() method to the Java IOGateway classes, so that you can change message encodings on the fly. - Made the IOGateway _outgoingEncoding variable private: use setOutgoingEncoding() and getOutgoingEncoding() to access it. - Merged in Nathan Whitehorn's patch to make FinalizeAsyncConnect() work properly under FreeBSD 7. - Merged in Nathan Whitehorn's patch to fix a bug in SSLSocketDataIO (previously, it could sometimes error out if the message length exceeded the network's MTU) - Rewrote the B_SWAP_* macros as C-compatible inline functions (previously they called the muscleSwapBytes() template function, which made them unusable in C programs) - Added the new replacement floating-point byte-swap API to support/MuscleSupport.h, including the following new functions: B_HOST_TO_BENDIAN_IFLOAT B_BENDIAN_TO_HOST_IFLOAT B_HOST_TO_LENDIAN_IFLOAT B_LENDIAN_TO_HOST_IFLOAT B_HOST_TO_BENDIAN_IDOUBLE B_BENDIAN_TO_HOST_IDOUBLE B_HOST_TO_LENDIAN_IDOUBLE B_LENDIAN_TO_HOST_IDOUBLE - Added a -DMUSCLE_AVOID_INLINE_ASSEMBLY flag that you can set if you want to avoid the use of inline assembly for some reason. - Changed the ConvertFromNetworkByteOrder() and ConvertToNetworkByteOrder() private virtual methods in the Message::PrimitiveDataTypeArray private class by changing them to operate on N items at once, instead of having to be called repeatedly for each item in an array. - PointerDataArray::ConvertFromNetworkByteOrder() and ConvertToNetworkByteOrder() now cause an assertion failure if called (because they should never be called: pointers aren't serializable) - Added a set of common comparison functions (Int8CompareFunc, Int16CompareFunc, Int32CompareFunc, Uint8CompareFunc, etc) to MuscleSupport.h because I was tired of reimplementing them separately every time I needed to sort a Queue or a Hashtable. - support/MuscleSupport.h now defines a new preprocessor constant, SELECT_ON_FILE_DESCRIPTORS_NOT_AVAILABLE, when compiled on an OS that doesn't know how to select on file descriptor (e.g. stdin). Currently that includes Win32 and BeOS. o Removed the GetChildren() and GetPulseChildrenIterator() methods from the PulseNode class, since they are no longer applicable. o Separated the single-argument Hashtable and Queue constructors into two separate constructors: a zero-argument default constructor, and a single-item constructor tagged "explicit". That way nonsensical conversions (e.g. myHashtable.Put(5)) get caught at compile-time rather than becoming hard-to-discover run-time errors. o Rewrote muscleSwapBytes() to use a union instead of pointer-magic. o The Java IOGateway classes are once again declared public instead of being package-private -- that way you don't have to use the MessageIOGatewayFactory class if you don't want to. o MakePrettyTypeCodeString() is now implemented as an inline function instead of a preprocessor macro. * Merged in Lior Okman's fix for the flattenMessage() methods in the MessageIOGateway classes, to make them work reliably with non-blocking sockets. * Fixed a bug in MessageTransceiverThread.cpp that would cause many of the commands sent to the internal thread to be received by all of the internal thread's sessions instead of just the intended target. * Fixed some bugs in testendian.cpp, and made its output prettier and more informative. * Removed the following functions from MuscleSupport.h: B_SWAP_FLOAT B_SWAP_DOUBLE B_HOST_TO_LENDIAN_FLOAT B_HOST_TO_BENDIAN_FLOAT B_HOST_TO_LENDIAN_DOUBLE B_HOST_TO_BENDIAN_DOUBLE B_LENDIAN_TO_HOST_FLOAT B_BENDIAN_TO_HOST_FLOAT B_LENDIAN_TO_HOST_DOUBLE B_BENDIAN_TO_HOST_DOUBLE Because they cannot be made to work reliably on x86-architecture chips. (See the FLOAT_TROUBLE and DOUBLE_TROUBLE comments in support/MuscleSupport.h for details) * Message.py's unit test now correctly reads and writes its file in binary mode. Thanks to David Rene for reporting this bug. v3.24 Released 11/28/2006 - The MacOS/X implementation of GetRunTime64() is now implemented using the CoreServices UpTime() function instead of POSIX times(), which makes it more efficient, allows it to return more accurate values, and avoids some potential problems with wrapping. - Added GetKey() and GetValue() convenience methods to the HashtableIterator class. - Added -- and ++ operators to the HashtableIterator class. - Added SetBackwards() and IsBackwards() methods to the HashtableIterator class. - Added a GetFlags() method to HashtableIterator class. - Added a new MessageFieldNameIterator constructor that takes a Message object. This is more efficient than calling msg.GetFieldNameIterator() and requires less typing. - Added ++ and -- operators to the MessageFieldNameIterator class. - Added a GetFieldName() method to the MessageFieldNameIterator class. - Each DataNode object now keeps a running maximum of the IDs in the child nodes that are attached to it. You can access this running maximum via the new GetMaxKnownChildIDHint() method. This value can be useful when generating a unique name for a new child node. - Also added a SetMaxKnownChildIDHint() method to the DataNode class. This lets you manually reset the hint if you need to. - Updated test/testhashtable.cpp so that it now tests for the HashtableIterator bug described below. - The MessageReplaceFunc callback used by CloneDataNodeSubtree() now takes a node-path as its first argument, in addition to the other arguments it took before. - The Python error strings generated by the ConvertMessageToPyObject() in PythonUtilityFunctions.cpp are now a bit more informative (they contain the problematic field name and/or type code) o Reduced the default output-stall timeout from 20 minutes to 3 minutes. o Removed the () operator from the MessageFieldNameIterator class because it was inconsistent with the operators of other iterator classes, and rarely (never?) used anyway. o Updated the copyright notices to 2007 Meyer Sound Laboratories Inc (a.k.a. the new owners of what was Level Control Systems) * The output-stall-detector mechanism would not disconnect moribund clients in a timely manner if the server was completely idle. Now it does. * Fixed a subtle bug in the HashtableIterator class that could cause the iterator to skip past the 2nd item in a traversal if the 1st item in the traversal was deleted at the wrong time. * Updated the portablereflectclient.cpp and portableplaintextclient.cpp example programs to include a hack-around for Win32's inability to select() on stdin. v3.23 Released 9/15/2006 - Added Nathan Whitehorn's SSLSocketDataIO class to the dataio subfolder. This class can be used to layer MUSCLE traffic over an SSL connection. Thanks Nathan! Note that this code requires the OpenSSL developer's toolkit to be installed before it will compile. - Enhanced the ParseArgs() routine to handle spaces intelligently (e.g. "x = 5" is now equivalent to declaring a key "x" with value "5", not declaring three separate variables named "x", "=", and "5") - Added Put() and Remove() methods to the Hashtable class that can put or remove the contents of an entire Hashtable at once. - Added NybbleizeString() and DenybblizeString() convenience functions to the MiscUtilityFunctions API. - Added a MUSCLE_USE_QUERYPERFORMANCEHARDWARE compile-time flag that tells MUSCLE to use QueryPerformanceCounter() under Windows instead of timeGetTime(). Specifying this flag improves GetRunTime64()'s accuracy, but QueryPerformanceCounter() is known to have problems on certain PC systems. * Fixed the Win32 and POSIX implementations of GetRunTime64() so that when the underlying OS clock "wraps" around to zero, it is detected and transparently handled so that the values returned by GetRunTime64() continue to increase monotonically. * Fixed the vc++/muscle.dsp project file so that things link properly again (thanks to Maurizio for help with this) * Added several tweaks to compile properly under MS Visual Studio 2005. * Made sure the files in the vc++ subfolder have Windows line endings. * Fixed a couple of bugs in the String class -- empty strings that had extra space preallocated in them could end up with unitialized garbage in them. * MuscleSupport.h now #defines WIN32 if _MSC_VER is defined. * Updated the QMessageTransceiverThread and QAcceptSocketThread classes further, so that they compile under Qt4 even when Qt3 compatibility support is disabled. * Fixed a problem under Win32, where GetSystemPath() would return an incorrectly formed path when unicode characters were present in the path name. v3.22 Released 7/5/2006 - Updated the Mutex, Thread, and QMessageTransceiverThread classes so that they are compatible with both Qt3 and Qt4. - Added a Python implementation of the zlib/ZLibUtilityFunctions.{cpp,h} API. It is in python/ZLibUtilityFunctions.py * Fixed a valgrind hit in the Linux implementation of GetSystemPath() * Commented out the buggy-QueryPerformanceCounter() warning under Win32, since it usually causes more confusion than enlightenment when it is printed. * Changed the custom-event codes in QMessageTransceiverThread.cpp and QAcceptSocketsThread.cpp to be in the allowed range for user-codes. * Added Lior Okman and Rony Gutherz' patches to re-enable compilation on 64-bit systems, Solaris, MSVC, and Windows 2000. * Added Mika Lindqvist's patch to allow use of the newnothrow macro under VC++6. * Updated the Makefile in the borland subdirectory to compile correctly. v3.21 Released 5/27/2006 - Added SYSTEM_PATH_USERHOME, SYSTEM_PATH_DESKTOP, and SYSTEM_PATH_DOCUMENTS, and SYSTEM_PATH_ROOT to the list of directories returnable by GetSystemPath(). - GetHostByName() now requires a second argument, (expandLocalhost), which determines whether 127.0.0.1 should be returned verbatim, or expanded out to the primary local IP address. - Added an (expandLocalhost) argument to the various AddNewConnectSession() methods that take a string for a hostname argument. - Added an (expandLocalhost) argument to the GetPeerIPAddress() function. - Added a RemoveEscapeChars() utility function to StringMatcher.{cpp,h} - Rewrote GetLocalIPAddress() to use the if_nameindex() API if it is available. If not, it will fall back to the old method of using gethostname(). - StorageReflectSession::SaveNodeTreeToMessage() and StorageReflectSession::RestoreNodeTreeFromMessage() now both take an optional (maxDepth) argument which can be used to specify the maximum depth of the node-subtree to be saved or restored. - The PR_COMMAND_GETDATATREES Message now has an optional PR_NAME_MAXDEPTH int32 field: If specified, the returned data trees will be clipped to the specified maximum depth - Added a PutAndGet() convenience method to the Hashtable class. This method puts a new object into the Hashtable, and returns a pointer to the object in the table. v3.20 Released 3/20/2006 - Added SetGlobalQueryFilterFactory() and GetGlobalQueryFilterFactory() calls, so that it is possible for MUSCLE-based servers to install their own custom QueryFilterFactory objects if desired. o Moved the DataNode class out into its own file, DataNode.{cpp,h}. It is no longer an inner class of the StorageReflectSession class. o All QueryFilter::Matches() methods now take a DataNode pointer as their second argument. None of the built-in QueryFilter subclasses use this value, but it is available so that custom QueryFilters can use DataNode information in their matching decisions if necessary. o Renamed InstantiateQueryFilter() to CreateQueryFilter(), and made it a virtual method in the new QueryFilterFactory class, instead of a global function. * Added serialization to muscleAlloc()/muscleRealloc()/muscleFree(), to avoid potential race conditions in multithreaded programs that have memory-usage-tracking enabled. * Fixed a bug in the Java receive code that could cause a parse error and subsequent disconnect if the Message stream was uncompressed (DEFAULT_MESSAGE_ENCODING) and a large Message was followed by a small one. * Fixed a typo in the java/build.xml file. * Rewrote MusclePowerPCSwapDouble() and MuscleX86SwapDouble() to use unions instead of C-style casting. Doing it this way makes them more readable and avoids errors due to uncontrolled interactions with g++'s optimizer. * Made the testendian test program a little more robust. v3.11 Released 3/1/2006 - Added a testsysteminfo.cpp test to the test folder, to test the functions in the SystemInfo.{cpp,h} files. - Merged in Lior Okman's updates to the muscle Java classes so that they now support the new, more efficient java.nio.* interfaces. Note that this means that the Java API now requires Java 1.4.0 or higher; let me know if that is a problem for you. - Added zlib/ZipFileUtilityFunctions.{cpp,h}, which contain functions that create a .zip file from a MUSCLE Message, and vice versa. Also added a testzip.cpp program to the test folder to test them. - Added a more convenient Inet_NtoA(uint32) function (that returns a String) to MiscUtilityFunctions.{cpp,h} o Optimized TCPSocketDataIO::FlushOutput() slightly under Linux. * Merged in Lior Okman's AMD-64 compatibility patch. * Patched NetworkUtilityFunctions.cpp to handle net_length_t properly under *BSD. v3.10 Released 1/16/2006 - Added the JCraft JZLib code to the included Java code tree, so that the MUSCLE Java code can again be compiled as provided. - Added a hashCode() method to the Java com.lcs.muscle.support.Point class. - Added NybbleizeData() and DenybbleizeData() convenience functions to MiscUtilityFunctions.{cpp,h}. - Added GetFirstKey(), GetFirstValue(), GetLastKey(), and GetLastValue() utility methods to the Hashtable class. - Added a HTIT_FLAG_NOREGISTER flag to the HashtableIterator class that (when specified) will prevent the HashtableIterator from registering itself with the Hashtable. This option allows you to do a 100% thread-safe Hashtable iteration, at the expense of requiring you to guarantee that the Hashtable won't be modified during the traversal. - Added a HasItems() convenience method to the Queue and Hashtable classes. This method returns true iff there is at least one item present in the object (i.e. it is the logical negation of the IsEmpty() method) - Added a HasNames() convenience method to the Message class. This method returns true if the Message contains any fields. o Removed the Flattenable::CopyToImplementation() methods since they were redundant. Instead, CopyTo() just calls CopyFromImplementation() with the arguments reversed. o Replaced the boolean (backwards) argument for HashtableIterators with a uint32 (flags) argument. Currently supported flags are HTIT_FLAG_BACKWARDS (same as backwards=true in older versions) and the new HTIT_FLAG_NOREGISTER (see above for details) o Inlined some trivial one-liner methods in the Message class, for efficiency. * Merged in Eli "Scanty" Dayan's portability fixes so that the code again compiles properly under Solaris. Thanks Scanty! * const methods in the Message class are now properly thread-safe (provided the Message object isn't altered by any other threads during their execution), thanks to the use of the HTIT_FLAG_NOREGISTER flag. * The math used in the MUSCLE_POWERPC_TIMEBASE_HZ implementation of GetRunTime64() would overflow after a week or two of uptime, causing GetRunTime64() to return incorrect results. Fixed. * PythonUtilityFunctions.cpp now compiles correctly under MacOS/X Tiger. * Tweaked MuscleSupport.h so that MacOS/X will properly use the x86 assembly language functions when running on an Intel-based system. v3.03 Released 10/10/2005 - Added a GetLocalIPAddress() function to NetworkUtilityFunctions.{cpp,h}. This function returns the IP address(es) of the machine it is running on. - Refactored the ThreadWorkerSessionFactory::CreateSession() method out into two methods: CreateSession() and CreateThreadWorkerSession(). That way subclasses can override CreateThreadWorkerSession() but still take advantage of the session-accepted-notification functionality present in CreateSession(). - MessageTransceiverThread now identifies sessions via their root node path instead of just their session ID. (e.g. "/192.168.0.5/17", not "17") - Added David Grossman's -DMUSCLE_PREFER_QT_OVER_WIN32 patch, so that you can choose at compile time whether Muscle should prefer to use Win32 or Qt APIs for its threading/synchronization mechanisms. - Added the 'cvscopy' utility program to the test folder. * GetPeerIPAddress() and GetHostByName() now call GetLocalIPAddress() if necessary to determine the local IP address, rather than returning 127.0.0.1. * GetSystemPath(SYSTEM_PATH_EXECUTABLE) would break under MacOS/X if the executable path contained any non-ASCII characters. Fixed. * GetSystemPath() was broken under Win32 if Unicode support was enabled. Fixed. * hexterm now compiles properly under MacOS/X. v3.02 Released 9/10/2005 - The second argument to Hashtable::GetOrPut() is now optional. - Merged in Lior Okman's changes to the Java client API: these included several bug fixes and the added ability to send compressed Messages. (If you have JZLib in your class path, you can receive compressed Messages also) - Added Lior's build.xml file for ant-based compilation and JAR-packaging of the muscle java API (into the java folder) - Added FailoverDataIO.{cpp,h} to the support folder. FailoverDataIO is a class that supports automatic failover across multiple redundant DataIO streams. - Connect() now takes an optional timeout argument, for people who are too impatient to wait for the operating system's standard TCP connect timeout period to elapse. - The ParseFile() function in MiscUtilityFunctions.{cpp,h} now supports hierarchical sub-sections (delimited in the text file with "begin foo" and "end" tag lines). - Added testparsefile.cpp to the test folder. o Moved the implementations of Inet_AtoN(), Inet_NtoA(), SetLocalHostIPOverride() and GetLocalHostIPOverride() from NetworkUtilityFunctions.cpp to SetupSystem.cpp, so that projects can include MiscUtilityFunctions.cpp without having to also include NetworkUtilityFunctions.cpp o Removed the MUSCLE_USE_CLONE support from the Thread class, since it didn't work properly anyway. * The Win32 implementation of the Thread class would leak a thread handle each time the internal Thread terminated. Thanks to Eivind Midtgård and Raymond Dahlberg for providing the fix! v3.01 Released 8/13/2005 - Added a "shared" parameter to the BindUDPSocket() function, to support the simultaneous reception of broadcast UDP packets by multiple processes on a single computer. - Updated the included zlib distribution to v1.2.3 - Updated the hexterm app to handle UDP packet I/O (in addition to the TCP stream and serial device data I/O it could do before) - Added equality (==) and inequality (!=) operators to the Hashtable class. * GetSystemPath(SYSTEM_PATH_EXECUTABLE) now returns the proper path under Linux (it uses the /proc filesystem to figure it out) * ChildProcessDataIO now uses the constants found in sys/ttydefaults.h to fill in the termios struct, instead of using hard coded magic numbers. v3.00 Released 7/12/2005 NOTE: THIS RELEASE BREAKS SOURCE CODE COMPATIBILITY WITH PREVIOUS RELEASES OF THE MUSCLE API. IF YOU HAVE CODE THAT WAS WRITTEN FOR PREVIOUS VERSIONS OF MUSCLE, YOU WILL NEED TO MODIFY IT SOMEWHAT IN ORDER FOR IT TO COMPILE AND RUN PROPERLY. SEE THE TWO ITEMS MARKED WITH (o) BELOW FOR DETAILS. - Added Matt Emson's client API for Delphi, in the "delphi" subdirectory. Thanks, Matt! - Updated the included zlib distribution to v1.2.2. - Added StoreTraceValue(), TCHECKPOINT(), SetTraceValuesLocation(), and associated functions to MuscleSupport.h. These functions can be useful in tracking down where code is executing at when a debugger isn't available. - Added a maxDepth argument to the LogStackTrace() call. - Added a PrintStackTrace() function to syslog/SysLog.{cpp,h}. This is similar to LogStackTrace(), but the stack trace goes directly to stdout instead of going to the log facility. - Added a "win32client" test/example app to the test folder. This app test/demos the Win32MessageTransceiverThread class. A VC++ project file (win32client.vcproj) is also included. - Added a SetSignalHandlingEnabled() method to the ReflectServer class, to allow servers to exit cleanly when an interrupt signal is received. - muscled now accepts an optional "catchsignals" argument that enables handling of interrupt signals (Control-C) to initiate a controlled shutdown. - muscleMax() and muscleMin() can now take up to five arguments, for convenience. - If you define the compiler constant MUSCLE_ENABLE_MEMORY_PARANOIA to an integer value (and also define MUSCLE_ENABLE_MEMORY_TRACKING), then the muscle memory allocator/deallocator code will add that many guard values to the front and end of all dynamically allocated buffers in order to detect bad memory writes. The guard values will be checked whenever the buffers are freed or resized, to make sure they haven't been overwritten, and it will also fill all allocated and freed buffers with special garbage bytes (0x55 and 0x66), so that it will be more obvious when freed or uninitialized memory is read. This slows down execution a bit and uses up extra memory, so it should only be enabled while debugging. - Added a MemoryParanoiaCheckBuffer() function to GlobalMemoryAllocator.{cpp,h}. Call this function to manually validate that an allocated memory buffer hasn't been corrupted. - All AbstractObjectRecycler objects (i.e. all ObjectPools) now register themselves in a global linked list, so that they can be iterated over. - Added the function GlobalFlushAllCachedObjects() to the AbstractObjectRecycler class. - Added a FlushCachedObjects() virtual method to the AbstractObjectRecycler class. This method is implemented in the ObjectPool subclasses to call Drain(). - The CompleteSetupSystem destructor now calls AbstractObjectRecycler::GlobalFlushAllCachedObjects(), so that all the ObjectPools get flushed before any static objects start getting destroyed. This helps avoid dangling pointer problems caused by the undefined ordering of static object destructor calls. - Added GetCount() and SetCount() methods to the AtomicCounter class, since it's occasionally necessary (albeit discouraged) to get or set the counter's value explicitly. - Added IsRefPrivate() and EnsureRefIsPrivate() methods to the Ref class to help facilitate Copy-on-Write semantics. - Added a FlushInput() method to the PlainTextMessageIOGateway class. - Added a BUILDOPTIONS.txt file to the muscle folder, to document the various compile-time flags that muscle uses. - Added WriteFully() and ReadFully() convenience methods to the DataIO class. These methods call Write() or Read() in a loop as necessary to guarantee that the whole buffer get written. - Added new convenience methods FlattenToByteBuffer(), UnflattenFromByteBuffer(), FlattenToDataIO() and UnflattenFromDataIO() to the Flattenable class, so that you can now Flatten()/Unflatten() to/from ByteBuffers and DataIOs with a single call when using blocking I/O. - Added a GetLength() convenience function to the Flattenable class, for easy determination of a DataIO's length in bytes. - Rewrote InflateMessage() and DeflateMessage() so that they spend less time holding the global muscle lock. o Changed all Ref arguments to be passed by const reference instead of by value. Note that this change will break most current Muscle-using source code -- your source code will need to be changed to match, in order for the virtual methods to be overridden properly. To update your code, you should change all function arguments of type BlahRef to (const BlahRef &). o Moved the AbstractObjectRecycler pointer out of the Ref class and into the RefCountable class, and changed it into an AbstractObjectManager pointer. Removed the recycler argument from all Ref class methods. This makes the Ref class a bit simpler and more efficient, but it also breaks existing source code. To update your code, you should change all instances of BlahRef(blah, NULL) to BlahRef(blah), and all instances of BlahRef(blah, NULL, false) to BlahRef(blah, false). o Replaced StorageReflectSession::DrainPools() with AbstractObjectRecycler::GlobalFlushAllCachedObjects(), which does the same thing but more thoroughly, since it flushes all ObjectPools and not just a few of them. o Moved a few overly large inline convenience functions into SetupSystem.cpp, for faster compilation and smaller binaries. o InflateMessage() now guarantees that the inflated Message will have the same 'what' code as the passed-in Message (the what code of the 'interior' Message is ignored). * Added a newnothrow_array #define to MuscleSupport.h and changed all the muscle code to use it instead of newnothrow when allocating arrays. This macro works the same as new (nothrow) for arrays, except it works around a bug in gcc 3.x that could cause crashes on memory failure. * ChildProcessDataIO now forces the removal if the SIGHUP signal handler in the child process, so that any grandchild processes will be cleaned up when the child process is killed. * Improved ChildProcessDataIO handling of restricted permissions on the /dev/tty* nodes. * Under Win32, if there were no sockets to select() on, select() would error out and the server loop would return. Fixed. * Log() and LogTime() could forget to unlock the global muscle lock if called re-entrantly. Fixed. * Fixed a nasty bug in the MUSCLE_POWERPC_TIMEBASE_HZ inline assembly implementation of GetRunTime64() that would cause GetRunTime64() to very occasionally go into an infinite loop. v2.65 Released 5/20/2005 - Optimized the String class by providing overloaded implementations of various common methods that take a (const char *) directly, rather than a (const String &). This eliminates much of the need for the compiler to construct and destroy temporary String objects when using string literals. - Added StartsWith() and EndsWith() convenience methods to the Queue class. o Made about a dozen one-liner String methods into into inline methods, to reduce CPU overhead in calling them. * Fixed a bug in the Windows implementation of ChildProcessDataIO that would cause the child process to be killed the first time it generated any text to stdout. * Fixed a problem in GetHumanReadableTimeValues() when compiling under Windows with pre-WinXP headers. Thanks to Mika Lindqvist for helping with this fix. * Added an #ifdef for _SOCKLEN_T to NetworkUtilityFunctions.cpp, so that net_length_t will be typedef'd properly on systems that need it. v2.64 Released 4/20/2005 - ConvertMessageItemToPyObject() now handles restoring list objects and dictionary objects. - testendian.cpp now does a bit more thorough job of testing the correctness of the byte swapping routines - Merged in Mika Lindqvist's patch to add inline-assembly implementations of the byte-swapping and atomic counter functions for the Win32/Visual C++ build environment. - Added Equals(char), EqualsIgnoreCase(char), EndsWith(char), EndsWithIgnoreCase(char), StartsWith(char), and StartsWithIgnoreCase(char) methods to the String class. - Added an optional (maxResults) parameter to ServerComponent::FindMatchingSessions(), and added a ServerComponent::FindMatchingSession() convenience method. - MuscleSupport.h now looks for a MUSCLE_FD_SETSIZE compiler constant; if found, it will use that to force the host's FD_SETSIZE to a new value (particularly useful under Windows where FD_SETSIZE is a pitiful 64... just add -DMUSCLE_FD_SETSIZE=512 to make it more reasonable) - Added a SetFromGenericUnchecked() method to the Ref class, for fast/unsafe reference-type conversion. - Added testtime.cpp to the test folder, to test MUSCLE's time/date handling functions. - GetCurrentTime64(), GetHumanReadableTimeValues(), ParseHumanReadableTimeString(), and GetHumanReadableTimeString() now all take a timezone argument that indicates whether the uint64 time value arguments are meant to represent local time or UTC. These parameters have default values that are set to preserve the previous behavior, for backward compatibility. o Moved QMessageTransceiverThread's event handling code out into a virtual separate method, called HandleQueuedIncomingEvents(). o Removed "volatile" keyword from the assembly byte-swapping inline function implementations, since it is not necessary and impedes optimization. * Merged in David Grossman's Visual C++ compatibility changes. * Fixed several bugs in the String class where memcpy() was being called in situations where memmove() was necessary. v2.63 Released 2/6/2005 - muscled now accepts "port=0" as a command line argument. This argument will cause muscled to choose an available TCP port to listen for incoming messages on. - Added a GetHumanReadableTimeValues() function to MiscUtilityFunctions.{cpp,h}. It's similar to GetHumanReadableTimeString(), except the results are returned as separate integers rather than as a String. - Added an optional "muscleSingleThreadOnly" bool argument to the ThreadSetupSystem and CompleteSetupSystem constructors. This flag lets you globally disable all Mutexes and other MUSCLE thread-safety mechanisms at run time. Useful if you need to compile your app without the MUSCLE_SINGLE_THREAD_ONLY compiler flag, but know (sometimes) at runtime that you will be running the process single-threaded... - Added a ChildProcessReadyToRun() hook method to the ChildProcessDataIO class. This method is called from inside the child process (except under Windows, which can't support it). - Added a GetSessionSelectSocket() convenience method to the AbstractReflectSession class. o ChildProcessDataIO now has a separate LaunchChildProcess() method, instead of launching the child process from inside the ChildProcessDataIO constructor. * Merged in Wilson Yeung's update to the C# client code -- this update fixes an infinite-loop bug and makes flattening and unflattening of Message objects more efficient. * NetworkUtilityFunctions.cpp once again compiles under BeOS. * Incorporated Stephane Petithomme's patch to allow muscle to compile correctly under SunOS. * Merged in Monni's patches to GetSystemPath() so that it handles Windows Unicode paths correctly. * Replaced the Win32 implementation of GetCurrentTime64() with a more standard (read: accurate) implementation. * The Windows implementation of GetHumanReadableTimeValues() was not quite accurate. Fixed. v2.62 Released 1/1/2005 - Added a SetUDPSocketBroadcastEnabled() function to the NetworkUtilityFunctions API. - Added a broadcastIP constant declaration to NetworkUtilityFunctions.h - Updated the "listener" test program to send hex bytes that are entered on stdin, to make outgoing TCP connections as well as accepting incoming ones, and to be able to connect to an RS232 serial port, if desired. Renamed "listener" to "hexterm" to reflect its expanded functionality. - Added an AdoptBuffer() method to the ByteBuffer class, so that you can populate a ByteBuffer with a pre-existing array of bytes, if you are careful about memory-ownership issues.. - Added a ChildProcessDataIO class, which is useful for spawning child processes and communicating with them interactively via their stdin/stdout streams. Works under POSIX, Windows, OS/X, and BeOS. - Added a RemoveANSISequences() function to MiscUtilityFunctions.{cpp,h}. This function strips all ANSI escape sequences from a given String. - Added a testchildprocess.cpp test to the test folder. This program is used to make sure ChildProcessDataIO works correctly. - Added a system/SystemInfo.{cpp,h} support API. These files contain a GetSystemPath() function (for locating various important directories on the host system), and a GetOSName() function that returns the name of the host operating system. o Adopted Jonas Sundström' simplified Makefile for muscled. * Updated the dev-c++/muscled.dev file to properly build muscled.exe again. * The included Python scripts are updated to raise exceptions using proper Exception objects, rather than old-style bare-string exceptions. * pythonchat.py now handles exceptions properly. * SharedMemory regions are now created with full permissions (0777) instead of just permissions for user and group (0770). * Worked around a gcc inline-assembly bug in the PowerPC assembly implementation of GetRunTime64(). (this bug would cause GetRunTime64() to sometimes return the wrong value if the MUSCLE_POWERPC_TIMEBASE_HZ compiler constant was defined) * Added some BeOS-compatibility tweaks to the RS232DataIO class. (I haven't really tested them to see if they work properly though) v2.61 Released 11/04/2004 - Added a CPULoadMeter class to the util subfolder. The CPULoadMeter class knows how to monitor the amount of CPU being used on your system. Handy for doing xload style status displays. Implemented for OS/X, Windows, and Linux only. - Added Jeff Koftinoff's Win32FileHandleDataIO class to the winsupport directory. - Added a "testtypedefs" test to the test folder. You can run this program to check that the MUSCLE typedefs (int8, int16, int32, etc) are correctly defined for your build environment. - Added SetMaxPoolSize() and GetMaxPoolSize() methods to the ObjectPool class. - Added a handy utility named "listener" to the test folder. This simple program just listens on a specified port and prints out (in hexadecimal) the bytes it receives from any connecting TCP client. - Added PLOCK() and PUNLOCK() macros to Mutex.h, and a new utility called deadlockfinder.cpp to the test subfolder. Together, these are useful for tracking down potential synchronization deadlocks in multithreaded programs. See test/deadlockfinder.cpp for details. * Added Peter Vorwerk's Tru64-compatibility patches. * Added Julien Torres' AMD64-compatibility patches. * Added an #ifdef to Thread.{cpp,h} so that the Thread class will compile properly with older (pre 3.2) versions of Qt. * Tweaked the code to again compile properly under BeOS/R5/PPC. * muscleFree now checks its argument for NULL-ness when memory tracking is disabled. v2.60 Released 9/25/2004 - Added in the initial implementation of the MiniMessage code. MiniMessage is a minimalist C-only implementation of the Message dictionary class, for use with C programs or C++ programs where simplicity and low resource usage is more important than flexibility and convenience. See the minimessage subfolder for details. - Added a Clear() method to the String class, for more efficient resetting of String objects. - Added a SetFromString() method to the String class, for more efficient copying of String objects. Changed the copy constructor and assignment operator to call this method instead of SetCstr(). - Added a constructor to the String class that takes a String and a maximum length in characters. - Added HashtableIterator constructors that take the Hashtable to iterate over as an argument, which is more convenient and efficient than calling table.GetIterator() - Rewrote the HashtableIterator construction code to be more efficient. - Added a compiler flag MUSCLE_AVOID_ASSERTIONS. If you specify this flag in your Makefile, all MASSERT statements will become no-ops. - MuscleSupport.h is now parseable as a C header file (the C++ portions of this file will be #ifdef'd out when compiling as C). The non-C++ inline functions in this file are now declared as 'static inline' to avoid linker problems when compiling C programs. o muscled is now compiled with optimizations enabled by default. To turn optimization off, compile muscled using 'make debug' instead. * Merged in Monni's patch to make the INT64_FORMAT_SPEC, the UINT64_FORMAT_SPEC, and the MCRASH_IMPL macros work correctly under Visual C++ 6.0. * Calling Destroy() more than once on a Python MessageTransceiverThread object would cause an exception to be thrown. Fixed. v2.52 Released 8/13/2004 - Added a GetInternalQThreadPriority() hook to the Qt implementation of the Thread class. This lets you specify the Thread priority of MUSCLE Threads launched from Qt programs, if you wish to. - Added a GetEmptyString() convenience function to the String class. This function returns a read-only reference to an empty string. * The Read() and Write() methods of the FileDescriptorDataIO class now return the correct values when used in blocking I/O mode. * Fixed a syntax error in Tuple::Replace() (thanks to Mika Lindqvist for bringing this to my attention). * Merged in Mika's patch to Message.cpp that fixes the template code so that it will compile without errors under gcc 3.4.1. * Rewrote the MuscleX86SwapInt64(), MuscleX86SwapDouble(), MusclePowerPCSwapInt64() and MusclePowerPCSwapDouble() inline assembly functions to work around problems with gcc's optimizer. * ParseArgs() now properly parses arguments with commas in them. * Integrated Wilson Yeung's fix for a race condition in the C# code. v2.51 Released 6/27/2004 - Wilson Yeung contributed an alpha version of a C# port of the Java client code (included in the "csharp" subdirectory). Thanks Wilson! - GetRunTime64() can now use the PowerPC time-base register, if running on a PowerPC CPU and you have #defined the compiler constant MUSCLE_POWERPC_TIMEBASE_HZ as the proper update rate. - Added SetMemoryAllocationStrategy() and GetMemoryAllocationStrategy() methods to the ByteBuffer class. You can call these to specify an IMemoryAllocationStrategy object that the ByteBuffer will use to allocate and free its buffers, instead of calling muscleAlloc() and muscleFree(). - The PlainTextMessageIOGateway class now has SetFlushPartialIncomingLines() and GetFlushPartialIncomingLines() methods, to govern whether "orphan" incoming text without a carriage return should be passed to the owner immediately, or whether it should be buffered until the carriage return is read. - Added in Monni's QNX compatibility patches. * Calling SetGateway() or SetDataIO() from within a ClientDisconnected() callback now does the right thing, instead of just immediately disconnecting the newly installed gateway (or DataIO) object afterwards. v2.50 Released 6/01/2004 - If using gcc on a PowerPC or x86 target, inline assembly will be used in the B_SWAP_* byte swapping macros, which is more efficient than the traditional muscleSwapBytes() template function. * IsRegexToken() now also returns true when passed in any of the following characters: =^+${}:- * Removed the kludgy workaround from Mutex.h that simulated a recursive pthreads Mutex using an int counter, and replaced it with a proper PTHREAD_MUTEX_RECURSIVE Mutex. Note that the new code requires a UNIX98 compatible pthreads implementation -- under Linux, you may need to add -D_GNU_SOURCE to your Makefile in order to use this code. v2.49 Released 5/07/2004 - The "daemon" keyword now takes an optional argument specifying where the daemon process's stdout and stderr should be redirected to. If no argument is specified, /dev/null will be used by default. - Added support in the Thread class for a MUSCLE_USE_CLONE compile flag. If specified, this flag tells the Thread class to use Linux's clone() system call to create new threads, instead of the pthreads API. If this flag is defined, the method Thread::SetCloneParameters() is available to specify the child thread's launch flags and stack size. - Added SwapContents() methods to the Message, ByteBuffer, and Ref classes. o StorageReflectSession methods SetDataNode(), RemoveDataNodes(), and InsertOrderedData() are now virtual. o The (createIfNecessary) argument to SpawnDaemonProcess() and BecomeDaemonProcess() now defaults to true. o ServerComponent::IsAttachedToServer() is now public. * ParseArgs() now handles comment # marks inside quotes properly. * Fixed a couple of Win32 incompatibilities. Thanks to Monni for reporting these. * SysLog.cpp wouldn't compile under BeOS/PPC. Fixed. * QMessageTransceiverThread::event() is now public and not a slot. * ByteBuffer::SetNumBytes() wasn't updating number-of-valid-bytes value correctly when called with retainData=true. Fixed. v2.48 - Released 3/17/2004 - Added a GetGroupSize() accessor method to the SharedUsageLimitProxyMemoryAllocator class. - Added ParsePort() and ParseConnectArg() convenience methods to the MiscUtilityFunctions.{cpp,h} files. These functions let you easily parse values out of "port" and "hostname:port" arguments. - Added an IsCallerInternalThread() method to the Thread class. This method returns true iff it's being called from the internal Thread itself, or false otherwise. - Added GetOwnerSocketSet() and GetInternalSocketSet() methods to the Thread class. These let you customize the blocking behaviour of GetNextReplyFromInternalThread() and WaitForNextMessageFromOwner(), respectively. - Added a ParseArgs() method to MiscUtilityFunctions.{cpp,h}. This method knows how to parse multiple arguments from a line of text. o The Thread class now prefers to use the Windows threading API over Qt threading when, both are available. * Connect() now logs an appropriate error message if a hostname lookup fails and logging is enabled. * Rewrote LogLineCallback::Log() to be more robust (it now calls vsnprintf() instead of vsprintf() and does proper bounds checking) * Fixed a problem with Message.py's parsing of 64-bit Message fields. Thanks to pyCube for reporting this bug! * Cleaned up miscellaneous errors in the autodoc header comments. v2.47 - Released 2/26/2004 - The muscle code now supports a -DMUSCLE_AVOID_NAMESPACES compile flag that will cause all namespacing directives to be commented out. * Fixed an off-by-one error in String::SwapContents() that would cause memory corruption if the longer of the two strings contained 7 bytes. * The SetFromArchive() methods of the AndOrQueryFilter and the NandNotQueryFilter classes were broken. Fixed. * UDP didn't work in Windows, because sin_family wasn't being set. Fixed. * Fixed a bug that would cause ambiguities in the semantics of the PR_RESULT_DATAITEMS Message, if a subscribed database node was updated and then deleted immediately afterwards. v2.46 - Released 1/27/2004 - Added some UDP support: There is now a UDPSocketDataIO class, and the following new NetworkUtilityFunctions: CreateUDPSocket(), BindUDPSocket(), SetUDPSocketTarget(), SendDataUDP(), and ReceiveDataUDP(). - Added some advisory timeslicing support to the PulseNode class. Now any PulseNode subclass can find out when its time-slice started, by calling GetCycleStartTime(), set a suggested time-slice-limit by calling SetSuggestedMaximumTimeSlice(), and check to see if that time limit is up by calling IsSuggestedTimeSliceExpired(). These methods can be used to help ensure consistent low latency to all clients. - Added a MathSetupSystem class (included in the CompleteSetupSystem class). This class disables BorlandC's floating point exceptions, to avoid crashing when a floating point exception occurs. - Added callback function arguments to CloneDataNodeSubtree(), to allow you to easily customize the Message payload of any nodes that it creates. - Added String::SwapContents() and Queue::SwapContents() methods for efficient (O(1)) state swapping between objects of these classes. - Added a HandleStandardDaemonArgs() function to MiscUtilityFunctions. This function parses command line arguments that are of general use. - Added a muscleSgn() convenience template function to MuscleSupport.h. o DisconnectSession() now returns a bool indicating whether or not the session decided to terminate itself. o Moved BecomeDaemonProcess() and SpawnDaemonProcess() from NetworkUtilityFunctions.{cpp,h} to MiscUtilityFunctions.{cpp,h}. o Rewrote muscledMain() to parse arguments using ParseArgs() and HandleStandardDaemonArgs(), rather than by looking at argv directly. o Rewrote Thread::InternalThreadEntry() to be cleaner. o Rewrote String::Replace() to be much more efficient. Also, it now returns the number of substring replacements done, rather than an error code. * Failed asynchronous-connect-attempts instigated by a call to AddNewConnectSession() were not being detected under Windows. Fixed. * Calling AbstractReflectSession::Reconnect() from inside the AbstractReflectSession::ClientConnectionClosed() method now works properly. * Calling AddNewSession(ref, int) with an AbstractReflectSession that already had a DataIO object installed would cause the pre-installed DataIO object to be deleted and replaced. Now the pre-installed DataIO object is retained, instead. * SharedMemory::SetArea() with a zero createSize parameter now works correctly under Windows. v2.45 - Released 11/10/2003 - Added GetNextKeyAndValue() convenience methods to the Hashtable class. - Added an Atoll() function to MiscUtilityFunctions, to complement the already included Atoull() function. - Added a Pad() convenience method to the String class, for easy padding of a string to a given minimum length. - Added SetSocketSendBufferSize() and SetSocketReceiveBufferSize() functions to the NetworkUtilityFunctions function collection. - Added a ConvertReturnValueToMuscleSemantics() function to MuscleSupport.h, and modified the various DataIO classes to call this function instead of each one reimplementing the conversion-logic separately. - Added QString-style Arg() methods to the String class, so that numeric values can be inserted into strings in a convenient and relatively safe manner. o Moved the PreviousOperationWouldBlock() and PreviousOperationWasInterrupted() functions from NetworkUtilityFunctions.h to MuscleSupport.h, since they weren't really networking-specific. o Moved the %llu's and %lli's into MuscleSupport.h constants INT64_FORMAT_SPEC and UINT64_FORMAT_SPEC, so that they are defined correctly for different compilers (some expect %Lu instead). * GetRunTime64() now contains a work-around for a bug in Windows' QueryPerformanceCounter() function that would cause time to "skip ahead" under certain motherboard chipsets. See system/SetupSystem.cpp for details. * Under Windows, GetCurrentTime64() was returning microseconds-since-1601. Fixed it to return microseconds-since-1970, as documented. * GetCurrentThreadId() was misspelled in Win32Support.h. Fixed. * Renamed the SWAP_* macros to B_SWAP_*, for consistency with the naming convention used in the other macros. * The FileDescriptorDataIO class now handles EINTR and EWOULDBLOCK return values appropriately, instead of erroring out. v2.44 - Released 09/15/2003 - The QAcceptSocketsThread and QMessageTransceiverThread constructors now take optional parent and name arguments, which are passed on to the QObject constructor. - The QAcceptSocketsThread and QMessageTransceiverThread destructors now call ShutdownInternalThread(), so you no lnoger have to call it yourself if you don't want to. - Added a setNotifyOutputQueueDrainedTag() method to MessageTransceiver.java, so that the user thread can be notified when the output queue drains. Thanks to Bryan Varner for this code. - Added a Replace() method to the Tuple class. * Some of the SetFromArchive() calls in MultiQueryFilter and its subclasses didn't mark their argument as const. Fixed. * Queue::AddTail(const ItemType *, uint32) was broken. Fixed. * Removed reference to QEvent::MaxUser from the QMessageTransceiverThread class, so that it can be compiled against Qt 2.3. * Replaced calls to QThread::postEvent() with QApplication::postEvent(). v2.43 - Released 08/19/2003 - Added an optional (count) argument to String::Append() and String::Prepend(). - Added a DisconnectSession() method to the AbstractReflectSession class. Calling this method force-disconnects the session's TCP connection. - PR_COMMAND_SETDATA now processes multiple sets to the same node in a single Message. - Added a (numPreallocSlots) argument to the Queue::EnsureSize() method, so you can specify how many extra slots to preallocate in the event of an array reallocation. - Added SetSignalHandle(), SetSignalValue(), and SetReplyThreadID() methods to the Win32MessageTransceiverThread class. * Fixed a bug in Hashtable::Clear() that could cause crashes under certain circumstances (iterators weren't being unregistered reliably). * Fixed a bug in the Queue class that was disabling queue-slot-preallocation, making calls to AddHead() and AddTail() inefficient -- O(N) instead of amortized O(1). Oops! * The Win32 implementation of GetHumanReadableTimeString() was returning date strings 369 years too early. Fixed. v2.42 - Released 7/15/2003 o DebugTimer's default minimum-print time is now 1000 (1 millisecond) o DeflateMessage()'s force parameter now defaults to true. * Fixed a bug in PathMatcher::MatchesPath() that would cause absolute paths to not be matched correctly. Thanks to VitViper and Monni for reporting this bug! * ReflectServer::GetServerUptime() was broken. Thanks to Monni for finding this bug! * The first call to Queue::EnsureSize() no longer does an implicit doubling of the initial array size, since it's likely that the caller to EnsureSize() has the best idea of how many slots are needed, and thus shouldn't be second-guessed. v2.41 - Released 6/27/2003 - Added an sdlsupport folder with Shard's SDLMessageTransceiverThread class in it. This class interfaces MUSCLE to the SDL game library. Thanks Shard! - Added a PRINT_CALLS_PER_SECOND macro to TimeUtilityFunctions.h - Added a PreviousOperationWasInterrupted() function to NetworkUtilityFunctions.h - ZLibCodec::GetInflatedSize() now takes an optional second argument which can be used to find out if the given compressed buffer is independent or not. - Added ZLibUtilities.{cpp,h} to the zlib folder. This file contains InflateMessage() and DeflateMessage() functions that are handy for compressing Messages down into a flattened state for efficient storage. - Added a muscleRealloc() function to GlobalMemoryAllocator.h, to go with the already existing muscleAlloc() and muscleFree() functions. - The String and ByteBuffer classes now use muscleRealloc() when appropriate, to avoid unnecessary data copying while resizing buffers. - Added a minimum-log-time argument to the DebugTimer class so that printing of very small time intervals can be suppressed. - Added a GetNumPreallocatedSlots() accessor method to Hashtable. - Added GetHumanReadableTimeString() and ParseHumanReadableTimeString() functions to util/MiscUtilityFunctions.h. These functions convert uint64 time values to ASCII "YYYY/MM/DD HH:MM:SS" strings, and vice versa. o SetupSystem's constructor is now protected, to make sure nobody declares a SetupSystem object by itself (they should use CompleteSetupSystem instead) o Removed the (copyBuffer) argument from the ByteBuffer constructor and several associated methods, because it was error prone and not very useful. * Fixed a crashing bug in Queue.AddHead(const Queue &) * SharedUsageLimitProxyMemoryAllocator::AllocationFailed() was broken. Fixed. * String::SetCstr() would store bytes past the NUL terminator of the passed-in string if (maxLen) was too large. Fixed. * Made String::Substring() is more efficient, and it now handles out-of-range values gracefully, instead of throwing an assertion failure. * The String constructor and SetCstr() took an int32 for (maxLen). Now they take a uint32 instead. * Replaced calls to CreateThread() with calls to _beginthreadex() in the Win32 implementation of the RS232DataIO and Thread APIs. * The (independent) flag to ZLibCodec::Deflate() wasn't working properly. Fixed. (The ZLibCodec header format has also changed slightly) v2.40 - Released 6/2/2003 - MUSCLE is now licensed under the standard BSD Open Source License. (Previously it used an equivalent but non-standard license) - Added the optional zlib compression library to the MUSCLE archive. (Add -DMUSCLE_ZLIB_ENCODING_ENABLED to your Makefile to enable it) - Added 9 levels of ZLib encodings to the MessageIOGateway class (MUSCLE_MESSAGE_ENCODING_ZLIB_1, ..., MUSCLE_MESSAGE_ENCODING_ZLIB_9) - Added QueryFilter objects (regex/QueryFilter.{cpp,h}) to allow queries to be restricted to include only nodes whose data Messages match user-specified criteria. - Rewrote the PathMatcher class and API to support QueryFilter objects. - Added a PR_NAME_FILTERS keyword that can be added to commands (along with PR_NAME_KEYS) to restrict results based on a QueryFilter. - Added a QueryFilterRef parameter to the SendMessageToMatchingSessions(), FindMatchingSessions(), and RemoveDataNodes() methods of the StorageReflectSession class. - Rewrote the MessageIOGateway implementation and protected API to use ByteBuffers, in order to better support ZLib encoding. - Added a PR_NAME_REPLY_ENCODING parameter to StorageReflectConstants. This parameter can be used to tell muscled to compress Messages that it sends back to your client. - Added a SetOutgoingMessageEncoding() method to the MessageTransceiverThread class. - Added a GetRunTime64() function to TimeUtilityFunctions.h. This function is similar to GetCurrentTime64(), except it is not synced to the real-time clock, and thus is guaranteed not to jump around (e.g. when the user sets the system clock, or during leap-seconds) GetRunTime64() is now used instead of GetCurrentTime64() where appropriate. - Added a Reset() method to all the AbstractMessageIOGateway classes, so that they can be re-used after a disconnect or parse error. - Merged in Bryan Varner's enhancements to the Java muscle code. These include a new Preferences wrapper class, and non-exception throwing get*() methods in Message class. Thanks, Bryan! - Calls to the installed LogCallbacks are now checked so that re-entrant calls (read: infinite recursion) cannot occur. - StorageReflectSession::SendMessageToSessions() and StorageReflectSession::FindMatchingSessions() now take a (matchSelf) boolean argument. - Optimized the Hashtable class to be a bit more efficient. - Added an AddPathFromString() convenience method to the PathMatcher class. - Added a muscleVoidPointer convenience typedef to MuscleSupport.h - Added IsReadyForInput() and HasBytesToOutput() methods to the AbstractReflectSession class; ReflectServer now calls these, and the default implementations pass the calls through to the gateway. - Added a GetOrPut() convenience method to the Hashtable class. (handy for demand-allocated Hashtable entries) - ByteBuffers no longer re-allocate their memory buffer when they are resized smaller. - Added DebugTimer.{cpp,h} to the utils subfolder. This class is useful for quick-and-dirty profiling of code execution times. - Added a GetTimeSliceElapsedTime() method to the ServerComponent class, so that sessions and factories can see how much time they have taken so far in their current cycle iteration. - Added an EnsureSize() method to the Hashtable class, to support pre-allocating tables (for efficiency). - Added item-array implementations of AddHead() and AddTail() to the Queue class. - Added optional startIndex and numItems arguments to the Queue-arg implementations of AddHead() and AddTail() in the Queue class. - Updated the Beginner's Guide HTML to document QueryFilters, ZLib encoding parameters, and a few other details that had been left out of it. o Moved the ByteBufferPool functions from Message.{cpp,h} to ByteBuffer.{cpp,h}. o Demoted certain log messages from MUSCLE_LOG_INFO priority to MUSCLE_LOG_DEBUG priority. o Adjusted the DECLARE_MUSCLE_TRAVERSAL_CALLBACK macro to make it more reusable in StorageReflectSession subclasses. o The ByteBuffer class now refers to its data as an array of uint8's, rather than using void pointers. * RateLimitIOSessionPolicy would divide by zero if you specified a rate limit of zero bytes per second. Fixed. * RS232DataIO::GetAvailableSerialPortNames() now works correctly under MacOS/X. * Fixed a couple of VC++-specific code problems. * Fixed a bug that was causing Messages sent to a MessageTransceiverThread to be sent back to the user thread. * StorageReflectSession::FindMatchingSessions() was broken. Fixed. v2.31 - Released 4/14/2003 - Rewrote the Hashtable class so that it no longer needs to allocate HashtableEntries dynamically during hash clashes. - Added in a remapping layer to the HashtableEntries so that Hashtable operations can be efficient even when the Hashtable is full or nearly full. Removed the (loadFactor) argument to the Hashtable constructor. - Lowered the Hashtable's default (initialCapacity) to 7. - Added some new optional parameters to StorageReflectSession's SetDataNode() and CloneDataNodeSubtree() methods to allow for more control over how nodes get placed into their parent's index. - Added muscleAlloc() and muscleFree() calls to the GlobalMemoryAllocator.h API, for those who like C-style memory management. - Added GetArrayPointer() methods to the Queue class. This enables efficient bulk-manipulation of items in the Queue. - Added an optional node-name argument to DataNode::InsertOrderedChild(). - Added an optional "releaseDataBuffers" argument to the Clear() methods of Queue, Hashtable, and Message classes, to force the immediate release of internally held memory buffers. - Added GetNumAllocatedItemSlots() method to the Queue class. - Added a muscleRintf() function to MuscleSupport.h - Added a Win32MessageTransceiverThread class to the winsupport folder. This subclass interfaces the MessageTransceiverThread class to the Win32 event API. - Added support for MUSCLE_DISABLE_DEBUGGING compile-time flag to turn all Log(), LogTime(), etc calls into no-ops. - Added a GetGlobalMuscleLock() function that returns a process-wide Mutex for simple serialization of Log operations, etc. - Added an argument for enabling Nagle's algorithm to CreateConnectedSocketPair(). Defaults to false/disabled. - Added a GetPosition() method to the DataIO interface and all subclasses thereof. * Fixed a bug in RestoreNodeTreeFromMessage() that would sometimes cause indexed nodes not to be restored. * Fixed a bug in Queue::EnsureSize(x, true) where sometimes it _itemCount wouldn't be properly set after a successful call. * Some of the byte-order-swap macros weren't handling complex arguments correctly. Added extra parentheses to fix them. * Added support for a -DMUSCLE_AVOID_NEWNOTHROW flag that will tell all MUSCLE code to use new instead of new (nothrow). * Trim() will no longer strip UTF8 chars from the end of a String. * Fixed a bug in the RateLimitSessionIOPolicy that would cause rate-limited transfers to occasionally stall. Thanks to Garjala for all his help in tracking this problem down! * Sessions that are about to be destroyed now have DoOutput() called on them, in case they have any last-second data to send. * Muscle now includes instead of to avoid gcc warnings. * MessageIOGateway::DoInputImplementation() would sometimes hold on to a large memory buffer instead of freeing it immediately. Fixed. * muscleAbs() was returning int instead of the templated type. Fixed. v2.30 - Released 3/03/2003 - Added a SharedMemory class to the system folder. This class acts as a platform-neutral wrapper API for the host OS's cross-process-shared-memory-area facilitities. - Rewrote the MemoryAllocator API to be more flexible. - ReflectServer's constructor now takes a MemoryAllocator pointer instead of a UsageLimitProxyMemoryAllocator pointer. - Added a SharedUsageLimitProxyMemoryAllocator class that uses a small shared memory area to allow multiple daemon processes to share a single aggregate memory-usage cap. - Added a Reconnect() method to the AbstractReflectSession class. This lets a session that was added with AddNewConnectSession() restore his connection if it breaks. - Added a GetSessionDescriptionString() method to the AbstractReflectSession class, for convenience. - Added GetAsyncConnectIP() and GetAsyncConnectPort() methods to AbstractReflectSession, for convenience. - Added a FindMatchingSessions() method to the StorageReflectSession class, for convenience. - GetPathDepth() now handles paths without a leading slash correctly. - Added SetSocketNaglesAlgorithmEnabled(), ShutdownSocket(), SendData(), ReceiveData(), and PreviousOperationWouldBlock() to the NetworkUtilities function collection. - Added IsBlockingIOEnabled() and IsNaglesAlgorithmEnabled() accessor methods to the TCPSocketDataIO class. - Added the AbstractGatewayMessageReceiver interface, and the QueueGatewayMessageReceiver convenience class. - Rewrote ReflectServer::ServerProcessLoop() to be slightly more efficient and fair. - Added a (void *) misc-utility argument to the MessageReceivedFromGateway() method, and made it part of the AbstractGatewayMessageReceiver interface. - Added testnagle.cpp and testresponse.cpp to the test folder. o Inet_NtoA() no longer returns a String object, since that requires the String class to be linked in to programs that could otherwise live without it. o Rewrote the AbstractMessageIOGateway API to be more efficient. Gateways no longer maintain a Queue of incoming Messages; rather, whenever they parse a Message they immediately pass it to a specified AbstractGatewayMessageReceiver object. o AbstractMessageIOGateway subclasses no longer override DoInput() and DoOutput() directly. Instead, they should implement/override DoInputImplementation() and DoOutputImplementation(). o Moved the StringMatcher and StringMatcherQueue singleton ObjectPools out of the StorageReflectSession class and into the StringMatcher.cpp and PathMatcher.cpp files, respectively. They can now be accessed anywhere, via the functions GetStringMatcherPool() and GetStringMatcherQueuePool(). o PathMatcher no longer accepts pointers to ObjectPools in its AddPathString() methods -- instead it just always uses the appropriate singleton ObjectPools. o Removed the type_code data type; now uint32 is used instead. o Removed the PulseNode::Tick() method hook, since it turned out to be unnecessary and encourages bad programming habits. * ReflectServer's status output is now more informative. * The ThreadSetupSystem and NetworkSetupSystem classes now handle multiple nested instantiations gracefully. * TCPSocketDataIO's Read() and Write() calls would return an error code for zero-length reads or writes. Fixed. * PathMatcher::MatchesPath() wasn't giving correct results for paths with leading slashes. Fixed. * TCPSocketDataIO::FlushOutput() wasn't working in OS/X. Fixed. v2.25 - Released 2/04/2003 - Renamed Hashtable::Get() to GetValue() (Get() is preserved as a synonym for compatibility with existing code) - Added two Hashtable::GetKey() methods to allow quick lookup of held key objects. - Added a PrintStackTrace() function to the SysLog module. MCRASH() and MASSERT() now call PrintStackTrace() so you get more debug info when you crash. (Only works under gcc) - Added a (setNumItems) argument to Queue::EnsureSize(), which can be handy if you want to add or remove a large number of default data items at once. - Updated MessageTransceiver.java with Bryan Varner's changes. - Hashtable::Sort() now uses Simon Tatham's very efficient merge-sort algorithm instead of insertion sort. - Added ToString() and AddToString() methods to the Message class. - Added a SetCstr() method to the String class. * binary String operators now return String instead of const String. * StorageReflectSession::CloneDataNodeSubtree() was not cloning node indices. Fixed. * DataNode::InsertIndexEntryAt() now uses GetKey() so as not to have to iterate over the node's child list. v2.24 - Released 11/15/2002 - Added an "oldData" argument to StorageReflectSession's NotifySubscribersThatNodeChanged() and NodeChanged() methods, and removed the NodeCreated() and NotifySubscribersOfNewNode() methods (since they are now redundant). - Added a "backwards" flag argument to Message::GetFieldNameIterator(), and added a Message::GetFieldNameIteratorAt() method. - Added a GetBlankMessage() convenience method to the StorageReflectSession class. This method returns a reference to an empty Message. - Optimized the tree search traversal algorithm so that non-wildcard patterns do a single hash lookup instead of matching against every child node. - Added GetPattern() and IsPatternUnique() methods to the StringMatcher class. - StringMatcher::SetPattern and the StringMatcher constructor now take a (const String &) instead of a (const char *). - Merged in Bryan's enhancements the the Java classes. The Jave MUSCLE API now includes better support in the MessageTransceiver class for listening for incoming TCP connections, and a way to interrupt() the current Thread running in a MessageQueue. - String::Replace() now returns a status_t to indicate whether any replacements were actually made or not. * QMessageTransceiverThread was using an illegal event code to signal the master thread of new network events. Fixed. v2.23 - Released 11/01/2002 - Added RS232DataIO.{cpp,h} to allow for simple serial port I/O. Currently it only works under Windows and Linux; support for other OS's may be added in the future, if there is need for it. - Exposed the AddPyObjectToMessage() function in the Python argument-conversion-utilities package. * Cleaned up the various comparison operators to return bool instead of int, and the equality-adjustment operators to return (Class &) instead of (const Class &) * Tweaked the code to compile cleanly under gcc 3.x. v2.22 - Released 10/16/2002 - Added PR_COMMAND_SETDATATREE, PR_COMMAND_GETDATATREE, and PR_JETTISON_SUBTREES commands, and a PR_RESULT_DATATREE reply. These can be used to conveniently get and set database subtrees. - MessageGateways now free their scratch buffers if they are bigger than 10 kilobytes, so as not to waste memory after having sent or received a very large Message. * Integrated Monni the Cat's VC++6 compatibility tweaks. * Fixed a horrendously embarrassing memory leak in muscled. In fact, ALL of muscled's heap memory allocations were being leaked, as of v2.18. Sorry guys, that was a really dumb mistake. :^( v2.21 - Released 10/08/2002 - Added a muscleAbs() utility template to MuscleSupport.h - Queue::RemoveItemAt() and Queue::InsertItemAt() have been optimized a bit -- they should be about twice as fast now. - Added a GetLogLevelKeyword() function to SysLog.h - StringMatcher::SetPattern() now looks for an optional tilde character ('~') at the beginning of simple patterns; if it finds it, it sets a negate flag so that Match() will return the logical opposite of what it usually would return. - Added manual SetNegate() and IsNegate() methods to the StringMatcher class. - IsRegexToken() now takes a second argument specifying whether the character in question is the first in the string (since there are several characters that are only 'special' when they are the leading character) - Database node paths are no longer cached, to save memory. Instead, GetNodePath() now generates the node-path on the fly, as needed. Because of this, the function signatures of GetNodePath() and GetNodeName() have changed. - Added a handy DataNode::GetPathClause() method that allows quick access to the node name at a specified depth in a node's path. * Queue::GetItemPointer() is now named GetItemAt(). (The old name is still available, but deprecated). * The PowerPC assembly implementation of atomic increment and decrement wasn't being used under OS/X. Fixed. v2.20 - Released 9/05/2002 - Added a () convenience operator to the MessageFieldNameIterator class. It operates as a synonym for GetNextFieldNameString(). - Added PythonUtilityFunctions.{cpp,h}, which currently includes two functions, ConvertMessageItemToPyObject(). and ParsePythonArgs(). These are useful when embedding Python and MUSCLE C++ code into the same application. - Added ParseArg() and ParseFile() methods to MiscUtilityFunctions .cpp and .h files. These parse an argument (ParseArgs()) style out of a single string, or a FILE pointer, respectively. - Added a GetScheduledPulseTime() to the PulseNode class. This method returns the time at which Pulse() will next be called. - Added a muscleCompare template that returns -1 if the first arg is greater than the second, or 0 if they are equal, or else 1. - Added an Atoull() function to turn an ASCII string into a uint64. (useful since atoll() and atoull() aren't standard functions) - Added a SendMessageToMatchingSessions() convenience method to the StorageReflectSession class. - Added a dev-c++ subfolder that contains project files suitable for compiling muscled under Windows' Dev/C++ IDE. (Thanks to Marcin "Shard" Konicki for supplying these!) - Added inline x86 assembly atomic-increment and atomic-decrement code to AtomicCounter.h. - Added a "remap" argument to muscled, and corresponding accessor methods to ReflectServer, to support explicit remapping of IP addresses (e.g. so you can tell muscled to advertise local LAN machines by their world-accessible IP address) * AtomicCounter.h no longer relies on the (non-portable) asm/atomic.h API when compiled under Linux. * ParseArgs() now parses argv[0] as well as the others. * BeOS/net_server bone-check in FinalizeAsyncConnection() now uses be_roster->IsRunning() if possible for more accurate results on systems where BONE has been installed and then disabled. * Fixed a bug that would cause an assertion failure if you called ReverseItemOrdering() on an empty Queue. * StringMatcher's wildcard-to-regex code was overly complicated and broken, especially when using the included regex parser (i.e. under Windows). Rewritten to be simpler and work right. * When set to a numeric-range pattern like "<0-50>", StringMatcher now only considers matches on strings that start with a digit. v2.19 - Released 7/22/2002 - Added a GetPathClauseString() method to PathMatcher.{cpp.h}. This version returns a String object containing just the one clause you specified. * GetPathClause() was not returning NULL on failure. Fixed. * When presented with an unknown hostname, MessageTransceiverThread would sometimes try to connect to IP address 0.0.0.0 instead of failing cleanly. Fixed. * The NodeCreated() callback would see the newly created node with an empty Message payload. Now it sees the node complete with the Message it was created to have. * The Win32 implementation of Thread::StartInternalThreadAux() wasn't handling the return value of CreateThread(), which in turn caused Thread::ShutdownInternalThread() to not work properly. Fixed. (Thanks to VitViper for detecting this bug!) * The BeOS/net_server implementation of FinalizeAsyncConnection() would cause net_server to half-close the connection after 60 seconds if no send or receive activity had occurred by then. Fixed. v2.18 - Released 7/4/2002 - Removed checks for DISABLE_MUSCLE_MEMORY_TRACKING, and put in checks for MUSCLE_ENABLE_MEMORY_TRACKING instead. In other words, memory tracking is now disabled unless the Makefile says otherwise. The muscled Makefile contains -DMUSCLE_ENABLE_MEMORY_TRACKING, so memory tracking is enabled by default for muscled. - Added two GetNumInstancesOf() methods to the String class; these are handy for counting how many instances of a substring are present in a String. - DefaultConsoleLogger now calls fflush() after every call to printf(). - Added a Reverse() method to the String class. - Added a muscleInRange() function template to MuscleSupport.h This function tests whether a given value is within a given range. * The 'maxmem' argument is no longer parsed if muscled was compiled without -DMUSCLE_ENABLE_MEMORY_TRACKING. * The '==' operator of the Message class had a bug in which Messages would sometimes be wrongly reported as equivalent when they weren't. Fixed. * Message class now holds its fields using a table of GenericRefs instead of AbstractDataArrayRefs (to avoid errors under compilers that don't like creating templates for declared-but-undefined classes) * The MemoryAllocator class hierarchy has been rewritten so that it no longer allocates or frees memory directly; rather it is used only to monitor and/or veto memory requests called in by the new and delete operators. This makes it work better with the constructors and destructors of static objects, and fixes a crash-on-exit bug in muscled. * Folded in Charlie Buckheit's SGI compatibility changes into the muscled Makefile, made the Makefile simpler, and added comments. v2.17 - Released 6/14/2002 - Message class now uses ObjectPools to cache extra AbstractDataArray objects, to avoid having to dynamically allocate them most of the time. You can define MUSCLE_DISABLE_MESSAGE_FIELD_POOLS to suppress this behaviour, if you need to. - AtomicCounter now uses inline assembly to implement atomic operations on the PowerPC processor with gcc, and the asm/atomic.h functions when under Linux/Intel. - Added '==' and '!=' operators to the Message class. - Modified Head() and Tail() in the Queue class to return read-only or read-write references to the head or tail items, instead of doing return-by-value. - Added PeekNextFieldNameString() and GetNextFieldNameString() methods to the MessageFieldNameIterator class. These return a (const String *) instead of a (const char *), which is sometimes more efficient. * MessageFieldNameIterator::PeekNextFieldNameString() was broken. Fixed. * AtomicCounter::AtomicIncrement() and RefCountable::IncrementRefCount() now return void instead of bool (Linux doesn't support returning bool) v2.16 - Released 6/5/2002 - Added SetNewInputPolicy(), SetNewOutputPolicy(), and RemoveSessions() methods to the MessageTransceiverThread class. These methods allow for some on-the-fly control of existing ThreadWorkerSessions. - Added comparison operators (less than, greater than, etc) to the Tuple class template. These do a lexical comparison using the comparison operators of each sub-element, in sequence. - syslog/SysLog.h now looks for a MUSCLE_MINIMALIST_LOGGING preprocessor constant. If found, Log(), LogTime(), and LogFlush() will be defined as simple in-line pass-throughs to printf(). This allows small programs to use MUSCLE classes without having to link in all the stuff that the regular logging facility requires. - Added GetKeyAt() and IndexOfKey() methods to the Hashtable class. - Added two Substring() convenience methods to the String class, that take a String as an argument. - Added a GetNumInstancesOf() method to the Tuple class. * To ensure logical correctness, all methods in the Hashtable class that used to return (Key *) now return (const Key *). * Folded in VitViper's Visual C++ compatibility fixes. v2.15 - Released 5/17/2002 - The Hashtable class now uses a HashFunctor template argument to calculate hash codes, instead of a function callback. This allows for more efficient code, but will break some source code (sorry!). To fix the souce, you typically just need to remove the function pointer argument to the Hashtable ctor. - Broke out the log-line-label-generation code in SysLog.cpp into its own separate function, GetStandardLogLinePreamble(), so that it can be accessed independently by other code. - Changed the Hashtable class's performance parameters to capacity=11, loadFactor=75%. This should save some memory. - Added an AfterMessageReceivedFromGateway() callback method to the AbstractReflectSession class. PushSubscriptionMessages() is now called by this method, rather than having to be called manually by the subclasses. - Added a CallMessageReceivedFromGateway() method to the AbstractReflectSession class. This method calls both MessageReceivedFromGateway() and AfterMessageReceivedFromGateway(), and should be used to 'fake' message reception (instead of calling the aforementioned methods directly). - Optimized the PushSubscriptions() method with a dirty-flag. - Added the muscleCopyIn() and muscleCopyOut() templates to MuscleSupport.h. These support alignment-safe value copying. - Added a GetEmptyMessage() utility function to Message.{cpp,h} - ObjectPool now derives from AbstractObjectManager, which in turn derives from AbstractObjectGenerator and AbstractObjectRecycler. This helps me use pools polymorphically. * The ServerComponent detach/delete sequence is now better defined, avoiding possible errors that could occur in custom servers. * A little more OS/X compatibility tweaking. * Some of the Flatten/Unflatten code would crash on processors (e.g. MIPS) that required values to be read on written on word-aligned boundaries. Fixed. (Thanks to Charlie Buckheit for reporting this bug) * Fixed a race condition in the Thread class that would cause the thread's owner to not be signalled correctly in some cases. v2.14 - Released 5/2/2002 * The Python Message implementation now flattens/unflattens B_INT64_TYPE fields properly even under old (pre 2.2) versions of Python. * Bryan Varner found and fixed a bug in the Java Message class; it wasn't handling the sending and receiving of UTF8 strings correctly. Thanks Bryan! * Removed the B_POINTER_TYPE from the Java Message implementation, since Java doesn't have pointers, and flattening a pointer into a Message that goes across the network is a silly thing to do anyway. * Changed all instances of #include to #include , since Muscle does not require any WinSock2-specific features. * The included fall-back regex library is now Henry Spencer's public domain implementation, instead of the GPL'd GNU version. * The Windows version of Thread::StartInternalThread() was broken. Thanks to VitViper for finding and fixing this bug! v2.13 - Released 4/26/2002 - Added Python support, with Message and MessageTransceiverThread classes, and pythonchat, a BeShare-compatible command-line demo chat app. Check out the README.TXT file in the python subfolder for details. - Added a readmessage.cpp utility to the test folder. - Added |= and &= operators to the Rect class. - StorageReflectSession methods NodeChanged(), NodeIndexChanged(), and NodeCreated() are now declared as virtual. * String::Trim() would crash with an assertion failure on some systems, due to incorrect handling of unsigned values. Thanks to Austin M. Brower (a.k.a. bobman) for catching this bug! * Tweaked the Makefiles and the SetupSystem.cpp file so that they compile properly under OS/X. (thanks again to Austin for this) * Fixed some problems that kept muscled from compiling under VC++. * Added a couple of checks to Message::Unflatten() to keep it from crashing if given a mangled flattened-Message to parse. v2.12 - Released 4/4/2002 - Added a SetAboutToFlattenCallback() method to the MessageIOGateway class. This allows you to install a hook that gets called when a Message is about to be flattened, in which you can modify or inspect the Message. - gcc now compiles muscled with the -fno-exceptions flag, resulting in somewhat more efficient code since muscle doesn't use exceptions anyway. - Added a muscleClamp() utility function to MuscleSupport.h. - Added << and >> operators to the Tuple declaration macros. - Removed the default/blank member items from the Tuple, Queue, and Hashtable classes, as I finally found a way to declare them properly on the stack instead. This should save some memory. * Snooze64() and GetCurrentTime64() were broken under Windows. Fixed. * Added a MUSCLE_MAX_OUTPUT_CHUNK #ifdef into ReflectServer.cpp, so that people with finicky routers can limit their send-chunk sizes by putting a -D flag into their Makefile if necessary. o Removed TCPSocketDataIO::PollSocketReadiness(), since it is never used, encourages polling, and causes warnings under C++Builder5.5. v2.11 - Released 2/28/2002 - Added RemoveDataNodes() and DoRemoveData() convenience methods to the StorageReflectSession API. - Changed the Thread class to have separate SetOkayToCloseInternalThreadWakeupSocket() and SetOkayToCloseOwnerWakeupSocket() methods, instead of passing in a "release" flag with the Get*WakeupSocket() calls. Also changed the Thread class to keep the socket values even when they are considered "released", so that signalling will still work if needed. * ThreadSupervisorSession::MessageReceivedFromOwner()'s argument list was missing a parameter, and thus it wasn't getting called. Fixed. v2.10 - Released 2/7/2002 - MUSCLE now supports compilation under Win32 using Borland's C++Builder 5.5 compiler. (use the Makefile in the 'borland' folder) - StringMatcher can now (as a special case) do simple integer range queries of the form "<15-252>", which would match strings. "15", "16", ..., "252". See StringMatcher::SetPattern() for details. - Added RemoveFirstInstanceOf() and RemoveLastInstanceOf() methods to the Queue class. - Added ByteBuffer and FlatCountable classes to the util folder. - Added AddFlat(FlatCountableRef), FindFlat(FlatCountableRef), and friends to the Message class. These allow you to add and retrieve FlatCountable objects to/from a Message by reference, so that they aren't actually flattened until the Message itself is. - Rewrote the Message class to use ByteBufferRefs instead of raw byte arrays for its flattened objects and raw data buffers. Note that this changes the semantics of these fields slightly-- copying a Message object will no longer copy the contents of these fields, but rather the two Messages will now both reference the same data. - Pointer fields in Messages are no longer flattened, as the mechanics of doing so are non-portable (and silly). - All methods in the Message class now take String references instead of (const char *)'s for field names. - Removed all but one of the Message::GetInfo() methods, since they were redundant and/or inconsistent with the rest of the Message API. - Moved the "okayToAdd" parameter of the Replace*() methods in the Message class to the front of the argument list. (It was causing some nasty problems involving type promotion at its previous position) - class ObjectPool now derives from an interface class named AbstractObjectRecycler. Also, the Ref class now holds a pointer to an AbstractObjectRecycler, rather than to an ObjectPool. This allows more flexibility when keeping heterogeneous sets of objects referenced. - Added optional CopyTo() and CopyFrom() methods to the Flattenable class. These methods support copying one Flattenable object to another in the most efficient way possible. Per-class optimizations can be implemented by overriding the CopyToImplementation() and CopyFromImplementation() virtual methods as desired.. * Default implementation of Flattenable::AllowsTypeCode() now accepts B_RAW_TYPE as well as TypeCode(), to allow unflattening from untyped data. * Removed the (char) constructor from the String class, as it was interfering with proper type checking of arguments. * Changed all index parameters in the Message class to use uint32 instead of int32 (since negative indices don't make sense). * MessageTransceiverThread wasn't adding new sessions asynchronously (i.e. after StartInternalThread() had been called). Fixed. * MessageTransceiverThread would not deliver a MTT_EVENT_SESSION_DISCONNECTED message to the user code if an asynchronous connection to localhost failed. Fixed. * FinalizeAsyncConnect() was using the wrong test and thus sometimes thought an asynchronous connection had succeeded when it had in fact failed. Fixed. * ConnectAsync() was broken under Windows. Fixed. v2.00 - Released 1/19/2002 - All MUSCLE code is now declared as being in the 'muscle' namespace. This, plus all the changes listed below, pretty much guarantee that any source code that compilable with previous versions of MUSCLE won't compile now, and vice versa; sorry about that. Hopefully everything that needed changing has been changed by now though, so it shouldn't happen again (well, not soon anyway ;^)). If you need help updating your old MUSCLE-using code, let me know. - muscled now parses a 'maxmessagesize' argument, allowing you to limit the maximum size of incoming Message objects (so e.g. you don't have to worry about some joker sending you 100 megabyte Messages, tying up all your RAM) - muscled now parses 'maxsessions' and 'maxsessionsperhost' keywords to allow limiting of the number of simultaneous connections, or simultaneous connections from any given client IP address. - muscled now accepts a 'localhost' keyword which lets you specify what the advertised IP address of clients connecting from localhost should be, instead of (the rather useless) 127.0.0.1. - muscle now accepts the keywords "maxsendrate", "maxreceiverate", and "maxcombinedrate" -- these allow you to specify maximum allowed bandwidth usage (in KB/sec) for sending, receiving, or both. - muscled now accepts a 'require' keyword on the command line as well as 'ban', allowing for 'whitelisting' as well as 'blacklisting'. - admin now parses 'require' and 'unrequire' keywords on the command line. - Removed the word 'Portable' from all class names that had it; since muscle is now in its own namespace, a unique prefix is no longer necessary. - Completely rewrote the MessageTransceiverThread class. Now the MessageTransceiverThread class is portable code, with optional thin OS-specific wrapper subclasses available if you wish to use them. Moreover, MessageTransceiverThread now holds its own ReflectServer object, which means that it uses the same event loop as the servers do, and that a single MessageTransceiverThread object can manage multiple incoming and outgoing connections simultaneously. BMessageTransceiverThread, QMessageTransceiverThread, and AMessageTransceiverThread are the wrappers for BeOS, Qt, and AtheOS, respectively. (MessageTransceiverThread can also be used by itself if you prefer to stick with threads-and-TCP only) - Split the accept-tcp-sockets-thread functionality into its own class, AcceptSocketsThread. There is also a Qt-specific subclass of of this available, named QAcceptSocketsThread. - Added a Tuple templated class to the support folder. This class represents an array of numeric values, and is used to do simple vector math operations conveniently. - Point and Rect (nee PortablePoint and PortableRect) are now derived from Tuple, to avoid code duplication. The formerly public member variables x, y, left, top, right, and bottom values are now exposed as inline methods instead (e.g. use x() instead of x). - Added aggregate bandwidth metering/management capabilities to MUSCLE. This includes the introduction of a new interface, AbstractSessionIOPolicy, and a bandwidth-limiter subclass, RateLimitSessionIOPolicy. - Added a SetMaxIncomingMessageSize() method to the MessageIOGateway class. - Added a FilterSessionFactory decorator class, that can be used in conjunction with any other ReflectSessionFactory object to enforce ban-lists, require-lists, and/or connection limits. - ReflectSessionFactory and AbstractReflectSession now have a common base class, named ServerComponent, that provides them with limited access to their ReflectServer object. - Added SetLocalHostIPOverride() and GetLocalHostIPOverride() functions to NetworkUtilityFunctions.h, to set a custom IP address to use instead of 127.0.0.1 when necessary. - Added -= and - operators to the String class. (you saw it here first!) - Added a String constructor and assignment operator for char arg. - Renamed ObjectPool::GetObject() to ObtainObject() to avoid a naming conflict with a #define in the MS-Windoze headers. (evil!) - ObjectPool class is now thread-safe by default (unless you specify -DMUSCLE_SINGLE_THREAD_ONLY in your build line) - Added a new subfolder named "system", which contains code for exporting OS-specified functionality in a platform-independent manner. This folder currently holds a Mutex class and a Thread class, both of which wrap the relevant portions of several supported native APIs: BeOS, AtheOS, pthreads, Qt, and Win32. It also holds the new MessageTransceiverThread and AcceptSocketsThread classes, since these are special types of Thread, and the GlobalMemoryAllocator. - Moved the memory-usage-tracking code out of ReflectServer.cpp and into its own file, system/GlobalMemoryAllocator.{cpp,h}. Now you can choose whether or not to link this in to your server. - Added util/MemoryAllocator.{cpp,h}. These files contain a set of memory-allocation-handler classes, which can be composed together to create a custom memory allocation strategy. Included subclasses include BasicMemoryAllocator, ProxyMemoryAllocator, UsageLimitMemoryAllocator, and AutoCleanupMemoryAllocator. - Merged PortableTypeConstants.h, PortableTypeDefs.h, PortableByteOrder.h, PortableMacros.h, and PortableStatusConstants.h into a single file called MuscleSupport.h - Renamed the BeOS and AtheOS conversion routines to ConvertToBMessage(), ConvertFromBMessage(), ConvertToAMessage(), and ConvertFromAMessage(). - Added a RawDataMessageIOGateway class to the iogateway folder. This class is handy for reading or writing chunks of unformatted bytes to/from a socket. - AbstractMessageIOGateway::DoInput() and DoOutput() now return the number of bytes that they read/wrote (respectively), or -1 if there was an error. (Before they returned a status_t). They now take a uint32 argument instead of a (uint32 &). The argument now indicates the maximum number of bytes they are allowed to read or write before returning. - Added an InsertOrderedData() method into StorageReflectSession so that subclasses can get more info about what gets inserted where. - Added new methods to the Message class: AddTag(), PrependTag(), FindTag(), and ReplaceTag(). These let you assign non-persistent, non-flattenable tag objects to a message that will be automatically dereferenced when the Message goes away. - ReflectSessionFactory classes are now in charge of deciding who gets to connect and who doesn't, rather than the StorageReflectSession class. This is useful because it means you can specify different access policies for different ports. - Removed AbstractReflectSession::GetClientPort() and replaced it with the (slightly more useful) GetPort() method, which returns the session's port number on the server side, instead. - Added AbstractReflectSession::SendMessageToFactory(), and ReflectSessionFactory::MessageReceivedFromSession(), so that sessions can send instructions to the factories that created them. - ReflectSessionFactory::CreateSession() now takes the IP string of the remote peer, to allow for filtering on IP addresses. - CreateAcceptingSocket() now takes optional arguments to return the selected port, and to specify an IP address to only accept from. - Added ConnectAsync(), FinalizeAsyncConnect(), GetHostByName(), CloseSocket(), Accept(), and Inet_AtoN() functions into the NetworkUtilityFunctions toolkit. Also added a version of Connect() that takes a numeric IP address rather than an ASCII string. - INet_NtoA() now returns a String instead of writing into a char buffer. - Added support for sessions that asynchronously connect outwards from the server: ReflectServer::AddNewConnectSession(), AbstractReflectSession::AddNewConnectSession(), and the callback AbstractReflectSession::AsyncConnectCompleted(). - Added SaveNodeTreeToMessage() and RestoreNodeTreeFromMessage() methods to StorageReflectSession. These allow easy recursive archiving and restoration of database node subtrees and their indices. - Made a bunch of formerly protected members of StorageReflectSession private, and added protected accessors for some of them, where necessary. - Added sort-by-value capability to the Hashtable class, and rewrote the auto-sort interface so that there are separate SetKeyCompareFunction(), SetValueCompareFunction(), and SetCompareCookie() methods, as well as associated accessor methods. - Added Message::GetNumValuesInName(). - GetMessageFromPool() now returns a MessageRef instead of a Message *, to avoid any possibility of a memory leak. - Added templated convenience functions muscleSwap(), muscleMin(), and muscleMax() to MuscleSupport.h. - Added a Shutdown() method to the AbstractMessageIOGateway interface, and made AbstractMessageIOGateway::GetDataIO() protected. - Added a GetSelectSocket() method to the DataIO interface. This method returns the socket fd to select() on for that DataIO (if any). - Removed AbstractMessageIOGateway::SetEnabled() and IsEnabled(), and replaced them with the single virtual method IsReadyForInput(), which function similarly to HasBytesForOutput(). - Consolidated the server-side Pulse logic into a single base class, PulseNode. ReflectServers, AbstractMessageIOGateways, ReflectSessionFactories, and AbstractReflectSessions now all inherit from PulseNode, and thus are all capable of scheduling and receiving Pulse() calls for themselves. Also renamed ReschedulePulseTime() to InvalidatePulseTime(). - AbstractDataIOGateway objects no longer take a DataIO pointer in their constructor arguments; instead, a separate SetDataIO(DataIORef) call is used to install the DataIO into the gateway. - Renamed the constant MUSCLE_NEVER_PULSE to MUSCLE_TIME_NEVER (since it is used in situations other than just Pulse() now). - Added the constant MUSCLE_NO_LIMIT, which is defined as ((uint32)-1). - Separated the DataIO creation from the CreateGateway() callback, making CreateGateway() implementations a bit simpler. Also added SetGateway() and GetGateway() methods so you can define a custom gateway for your session "in advance" if you want to. - Added SetRef(), SetFromGeneric(), and GetGeneric(), conveniences methods to the Ref class, as well as a Ref constructor that takes a GenericRef. - Renamed AddLogCallback() to PutLogCallback(), and change the arguments to take a LogCallbackRef instead of just a pointer. - Moved the log callback stuff into its own header file, syslog/LogCallback.h - Modified several APIs that were taking a pointer and an "ownIt" boolean to take Refs instead. That way the deletion can be handled automagically. - Removed the InitializeTCPStack() method from NetworkUtilityFunctions and added instead some SetupSystem classes, including a ThreadSetupSystem, a NetworkSetupSystem, and a CompleteSetupSystem. Placing one of these (usually a CompleteSetupSystem) on the stack at the beginning of main() is now the correct way to handle all environment setup and tear-down. - Added MiscUtilityFunctions.{cpp,h} files to the util subfolder. These contain utility functions that don't fit in anywhere else--currently they contain a ParseArgs() function that parses command line arguments into a Message object. - Added the SignalMessageIOGateway class -- a very simple gateway used primarily as a convenience class for thread synchronization. - Renamed MessageReceivedFromNeighbor() to MessageReceivedFromSession(), and renamed BroadcastMessageToNeighbors() to BroadcastMessageToSessions(). - Added MessageReceivedFromFactory() and BroadcastMessageToFactory() methods to the ServerComponent class and its subclasses. - Added util/SocketHolder.h, to facilitate leak-proof socket file descriptor transfers via Message objects. - merged testreflectclient.cpp and testatheosclient.cpp into a single program, and got rid of testplaintextclient.cpp * Renamed Queue::CountItems() to GetNumItems(), and renamed Hashtable::Size() to GetNumItems(), for clarity and consistency. * Renamed all methods named MakeEmpty() to Clear(), for consistency. * functions in the SysLog API are now serialized in order to be thread-safe. * Removed the UnintrusiveRef class, as it isn't useful enough to keep around. * Fixed a bug in the PlainTextMessageIOGateway that would sometimes allow garbage characters into the imported text. * All TCP port number arguments are now specified as uint16s instead of ints. * All usages of size_t and ssize_t have been replaced with uint32 and int32, respectively (since that is more explicit/precise). * Removed the MUSCLE_CLASS_DECLARATIONS and MUSCLE_FUNCTION_DECLARATIONS tokens from the headers, since they didn't have a well-defined meaning. * Certain MUSCLE methods were using a non-standard convention of returning a boolean value to indicate success or failure. Modified all of the following methods to return a status_t (B_NO_ERROR or B_ERROR) instead: HashtableIterator::GetNextKey() HashtableIterator::PeekNextKey() HashtableIterator::GetNextValue() HashtableIterator::PeekNextValue() Hashtable::Get Hashtable::Put() Hashtable::Remove Hashtable::RemoveAux() Hashtable::GrowTable() Hashtable::MoveToFront() Hashtable::MoveToBack() Hashtable::MoveToBefore() Hashtable::MoveToBehind() Hashtable::Sort() Queue::AddTail() Queue::AddHead() Queue::RemoveTail() Queue::RemoveHead() Queue::RemoveItemAt() Queue::GetItemAt() Queue::ReplaceItemAt() Queue::InsertItemAt() Queue::EnsureSize() AbstractMessageIOGateway::EnsureBufferSize() Message::GetNextFieldName() Message::PeekNextFieldName() StorageReflectSession::DataNode::PutChild() StorageReflectSession::DataNode::InsertOrderedChild() StorageReflectSession::DataNode::ReorderChild() StorageReflectSession::DataNode::RemoveIndexEntry() StringMatcher::SetPattern() Flattenable::ReadData() v1.93 - Released 12/05/2001 - Added an optional second argument to PortableHashtable::GetIterator(), that lets you traverse the hashtable's contents backwards. - Added PortableHashtable::GetIteratorAt(), to allow iterations that start from any item in the table's traversal list. - Changed the compare function type for hash tables to return an int (strcmp() style) rather than a bool (== style), so that it can be used for sorting as well as comparison. Also added a (void *) cookie parameter so that the callback can access user-defined context information easily. - Changed PortableHashtable::SetCompareFunction() to take a second parameter specifying whether or not the compare function should be used to auto-sort entries as they are placed into the hash table. - Added Sort() and Sort(compareFunc) methods to PortableHashtable to allow in-place traversal order sorting. - Added the PR_COMMAND_REORDERDATA message type, to let clients reorder their indices without having to delete and reupload the associated data nodes. v1.92 - Released 11/23/2001 - PortableHashtables now retain the ordering of the items you Put() into them. (And since PortableMessage uses a PortableHashtable internally, this means also that PortableMessage now retains the ordering of the data fields you add to it) - Added MoveToFront(), MoveToBack(), MoveToBefore(), and MoveToBehind() methods to the PortableHashtable class. These methods allow the user to modify the iteration traversal order. - It is now possible to modify a PortableHashtable in the middle of traversing its contents with a PortableHashtableIterator, without causing an assertion failure or even messing up the traversal(!). - Renamed PortableHashtable::Contains() to ContainsValue(), to avoid confusion. - Rewrote PortableHashtableFieldNameIterator to be simpler and more efficient. - Rewrote ReflectServer to use only a PortableHashtable to hold AbstractReflectSessionRefs, instead of both a PortableHashtable and a PortableQueue. - Renamed ReflectServer::GetSessionsList() and AbstractReflectSession::GetSessionsList() to GetSessions(), which now returns a hashtable iterator instead of a reference to a PortableQueue. - Renamed ReflectServer::GetSessionByID() and AbstractReflectSession::GetSessionByID() to GetSession(), which now returns an AbstractReflectSessionRef instead of a status_t. - Added a +(char) operator to PortableString class. - Made the non-session-specific server API access methods in AbstractReflectSession protected, instead of public. - Added a SwapContents() method to the PortableHashtable class. * Fixed the GrowTable() method -- the user compare function wasn't being retained. v1.91 - Released 11/01/2001 - Added atomic inc/decs for Linux and Windows into PortableRefCount.h - The admin tool now waits for a response from the server, and informs you if your admin commands failed due to a privilege violation. - Changed GetPeerInfo() to try and find out what the local host's "real" IP address is if necessary, instead of returning 127.0.0.1. - moved the signal(SIGHUP, SIG_IGN) code into InitializeTCPStack(). * Integrated Vitaliy's patches to get QMessageTransceiverThread to work under Windows. v1.90 - Released 10/26/2001 - Changed the PortableRefCount class to require that the items it reference-counts are subclasses of PortableRefCountable. This has the advantage of removing all the RefCountMem and RefCountMemPool dependencies; unfortunately it also breaks most of the MUSCLE-using code out there (slightly). The old PortableRefCount implementation is now called UnintrusivePortableRefCount, and is left in for use in cases where the reference-counted class cannot be modified to derive from PortableRefCountable. - Added a StorageReflectSession::CloneDataNodeSubtree() convenience method. - Added a CreateAcceptingSocket() function to NetworkUtilityFunctions. This function creates and returns a socket that is listening for incoming TCP connections on the given port. - Added a Flush() callback method to the LogCallback class, and a LogFlush() global function, so that SysLog output can be fflush()'d in a generic manner. - Added support for defining a custom threadsafe incrementor function in PortableRefCount.h - Added #define PR_NAME_SESSION "session" into StorageReflectConstants. Now when muscled sees a string with this field name in a client-to-client PortableMessage, it will replace the string value with the sending client's session ID. This allows receiving clients to be sure that the client who sent them the message is the client indicated in the server field of the message (i.e. it disallows "spoofing" of other clients). - Added an example flattened-PortableMessage byte listing to the end of PortableMessageIOGateway.h - Added AddHead() and AddTail() methods to PortableQueue that take other PortableQueues, rather than individual items. - QMessageTransceiverThread::PortableMessageReceived()'s second argument is now a uint32 instead of an int. - Added the InitializeTCPStack() function to NetworkUtilityFunctions.h (Starts up the TCP stack; only needed under Windows) - Added handy factory functions for the PortableMessageIOGateway and PlainTextMessageIOGateway classes. - Added the LogLineCallback convenience subclass to SysLog.{cpp,h} - Added Vitaliy's vc++ subfolder with VC++ project files. * More windows compatibility tweaks; muscled now compiles and runs under Windows XP with VC++! (many thanks to Vitaliy Mikitchenko aka VitViper!) * StorageReflectSession::NodePathMatcher::DoTraversal() was not giving correct results for traversals that used multiple query strings and didn't start from the global database root. Fixed. v1.84 - Released 10/15/2001 - Added a SpawnDaemonProcess() function to NetworkUtilityFunctions.h - Added a Snooze64() function to NetworkUtilityFunctions.h - Added ReleaseFile() and GetFile() methods to FileDataIO.h - Added a PR_NAME_SET_QUIETLY tag so you can upload nodes to the database without causing subscribers to be notified. - Added a PR_NAME_REMOVE_QUIETLY tag so you can remove nodes from the database without causing subscribers to be notified. - Added Jonathon Padfield's QSocketDataIO class to the qtsupport folder (for single-threaded Qt programs). Thanks, Jonathan! - Added a MCHECKPOINT macro to PortableMacros.h for use in debugging. - Added a RemoveAllInstancesOf(const ItemType &) method to the PortableQueue class. - Added == and != operators to the PortableQueue class. - testgateway.cpp now takes optional filename arguments. Any filenames given to it will be read as flattened PortableMessages and their contents printed to stdout. - Added a OnceEvery(uint64, uint64 &) function to TimeUtilityFunctions.h - PortableMessage::PrintToStream() now has optional arguments to make it function recursively with varying levels of indentation. - Added a new class regex/PathMatcher.{cpp,h} to the repertoire. This class can be used to do efficient pattern matching against node-path strings. Moved the functions in reflector/StorageReflectUtils.{cpp,h} into these files instead. - Previously subscribing to a string you were already subscribed to was a no-op. Now it is equivalent to a PR_COMMAND_GETDATA using that string. - PortableQueue::Sort() now takes an optional void pointer that will be passed through to the item-compare callback function. * Jonathon Padfield contributed a patch to PortableByteOrder.h to make it compile under FreeBSD. Thanks again J :^) * PortableRef class now has a proper copy-constructor. * Changed B_ERROR and B_NO_ERROR declarations from an enumeration to #defines, to avoid compiler warnings. * Fixed a bug in QMessageTransceiverThread that would cause TCP connections to be broken as soon as they were connected. * TCPSocketDataIO::Shutdown() now calls shutdown() before close(). (Linux wasn't being properly punctual with just close()) * PortableString::Unflatten() now checks to make sure the flattened string is terminated, and errors out if it isn't. * PortableHashtable::Put()'s default value for the last argument was false instead of NULL. Fixed. * Made several methods in StorageReflectSession inline and const tagged. v1.83 - Released 9/12/2001 - Added a qtsupport folder, containing QMessageTransceiverThread and QThreadSafeObjectPool classes for use with the Qt API. - Added more of David Rene's Visual C++ compatibility changes in. - Renamed GetCurrentTime() to GetCurrentTime64() to avoid a conflict with the like-named Windows function, and added David's Win32 implementation of the method. - Added MUSCLE_CLASS_DECLARATIONS and MUSCLE_FUNCTION_DECLARATIONS tokens into the header files where appropriate. These tokens are #defined to nothing by default, but can be overridden by the compile environment (-D flag) if necessary. - Added an "okayToAdd" argument to all the Replace*() methods in the PortableMessage class; if set to true, then attempting to replace a non-existing item will cause the new item to be added to the message instead of returning B_NO_ERROR. If set false, the old behaviour (fail if old item not present) is used instead. - Added a Reset() method to the MessageTransceiverThread classes. You can call Reset() on a MessageTransceiverThread object to re-initialize its state (comparable to deleting the MessageTransceiverThread object and creating a new one) - Added GetOutputStallLimit() methods to the AbstractMessageIOGateway, PortableDataIO, and TCPSocketDataIO classes. Now output stall detection is only done on TCP connections, and can be controlled per gateway or per data io type. - Changed the ReflectServer to take a ReflectSessionFactory object in PutAcceptPort() instead of a callback function. Converted all session creation callback functions into ReflectSessionFactory subclasses. - Added an overloaded () operator to the StringTokenizer class, as a convenience. It works as a synonym for GetNextToken(). v1.82 - Released 8/21/2001 - During a memory shortage, muscled now kicks users whose output message queues have grown too large. This keeps someone with a bad network connection and an ambitious subscription request from tying up all the memory on the server indefinitely. - Changed the signature of AbstractMessageIOGateway::DoInput() and AbstractMessageIOGateway::DoOutput() to DoInput(uint32 & addReadBytes) and DoOutput(uint32 & addWroteBytes). DoInput() and DoOutput() should add to this argument the number of bytes they read or wrote during the call, respectively. This helps the calling code know when I/O is stalled. - muscled now keeps track of how long an output has been "stalled" (i.e. it has bytes queued to send to the client but none have actually been sent) and will drop any clients that have been stalled for more than 20 minutes. v1.81 - Released 7/16/2001 - Added Alan's stream operators ("<<") to the PortableString class. * Made AtheOS refcounts use atomic_add(), for thread safety. * Merged in David Rene's header tweaks to help MUSCLE code compile cleanly under Visual C++. * Tweaked time.h includes to compile properly under Debian Linux. * Messages being returned to the global message pool now have their 'what' code set to zero. * Fixed a potential source of problems during out-of-memory conditions in the PortableMessageIOGateway class. v1.80 - Released 6/26/2001 - Added an atheossupport directory, which is a AtheOS port of the BeOS code in the besupport directory. - Added testatheosclient.cpp and testatheossupport.cpp testing stubs to the test folder. * Consolidated the netutil, string, stringtokenizer, hashtable, refcount, pool, and queue subfolders into a single subfolder named 'util'. All code that uses MUSCLE will probably need to have its #include lines modified to reflect this, before it will compile again. :^( (this change was necessary in order to avoid #include space conflicts with the STL headers) v1.72 - Released 6/22/2001 - Added a "maxnodespersession" parameter to muscled, which lets you specify the maximum number of nodes any given session may have in its server-side database at one time. - Added a uint32 PR_NAME_MAX_NODES_PER_SESSION read-only parameter to the parameter set returned by PR_COMMAND_GET_PARAMETERS. This returns the value mentioned above. - Made some of the members of the DataNode class demand-allocated, so as to use a little less memory. - Tweaked the code to compile without errors under the CygWin environment. (thanks to Joshua Schmiedlin for his help with this) - Added a Sort() method to the PortableQueue class. This method uses a nice in-place merge-sort algorithm that I liberated from Thomas Baudel's sorting visualizer applet at http://www-ihm.lri.fr/~thomas/VisuTri/ - Added Swap() and ReverseItemOrdering() methods to PortableQueue. These let you swap two entries or a invert the ordering of a whole range of entries, respectively. - ReflectServer now preallocates 256 slots for the lame-duck session list, so that adding a session to the lest is less likely to fail during a memory pinch. - Added a SetNotificationMessage() method to MessageTransceiverThread class (in case the regular old PORTABLE_MESSAGES_RECEIVED message isn't good enough for you) v1.71 - Released 6/11/2001 - Renamed ReflectServer::AddAcceptPort() to PutAcceptPort(). Changed ReflectServer to allocate accept-sockets inside the PutAcceptPort() call instead of at the beginning of the ServerEventLoop(). Also added a RemoveAcceptPort() method to ReflectServer, and added PutAcceptPort() and RemoveAcceptPort() pass-through methods to AbstractReflectSession. - Added a BroadcastToAllNeighbors() convenience method to the AbstractReflectSession class. - Added a Seek() method to the PortableDataIO interface, and Seek() implementations to the various subclasses thereof. Moved FileDescriptorDataIO's implementation into a .cpp file so that it will link properly under Linux. * Added some missing constants to StorageReflectSession.java v1.70 - Released 5/20/2001 - Changed the Makefiles to reflect the changed, final location of the BONE headers (/boot/develop/headers/be/bone) - Changed the Put() methods of PortableHashtable to return true on success, false on error (memory allocation failure). NOTE: This changes the Put()'s return value semantics! If you code was relying on them, you will need to modify it. - Changed ReflectServer::ServerProcessLoop() to take no arguments, and added a method ReflectServer::AddAcceptPort(func, port) instead. This change allows a single server to accept connections on multiple ports if it wants to, and create different AbstractReflectSession objects based on the port the TCP connection was received on. As a consequence of this, you can now have muscled listen on multiple ports if you like; e.g. muscled port=2960 port=4000 port=9999 - Added a GetServerUptime() method to the ReflectServer and AbstractReflectSession classes, and a PR_NAME_SERVER_UPTIME field to the message returned by PR_COMMAND_GET_PARAMETERS. The value returned is muscled's uptime, in microseconds. * Changed the AddLogCallback() and AddOutOfMemoryHandler() functions to return B_ERROR on out-of-memory. * Changed the muscled code to handle Put() failing a little better. This should fix some of the memory leaks that occur when the server has hit its memory cap. v1.64 - Released 5/07/2001 - Added dataio/MemoryBufferDataIO.h. This class lets you use an in-memory array as a limited input or output device. - Added a new first parameter to BecomeDaemonProcess(). This first param lets you specify the directory that the child process should chdir() to. Leave as NULL to not change directory at all. - Added a GetReadByteTimeStamp() method to the PortableDataIO interface. (used to support high-precision time-stamping in LCS-specific subclasses. Not implemented by any of the included MUSCLE classes, though) - Added a PR_COMMAND_BATCH message type. When the server receives this message, it will parse the submessages in the PR_NAME_KEYS field and execute them in order as if they had arrived separately. - Added a PR_COMMAND_NOOP message types. When the server receives this message it is guaranteed to do nothing at all with it. - In the StorageReflectSession class, changed NotifySubscribersOfNewNode(), NotifySubscribersThatNodeChanged(), and NotifySubscribersThatNodeIndexChanged() to be virtual so that they can be overridden and used as hooks in a subclass. - Added a CreateConnectedSocketPair() function to the NetworkUtilityFunctions.h package. This function is useful for thread coordination. - Added a SetSocketBlockingEnabled() function to NetworkUtilityFunctions.h - muscled now compiles and runs under AtheOS, thanks to a patch submitted by Jonas Sundstrom. * The docs were referring to the muscled's pattern matching feature as 'regular expressions'. This was inaccurate, as muscled doesn't parse regular expressions so much as wildcard expressions, a.k.a. globbing. Changed the docs to reflect this. * PortableString::LastIndexOf(char) was broken. Fixed. * Boolean PortableMessage fields were broken on architectures where sizeof(bool) was not equal to one. Fixed. v1.63 - Released 3/25/2001 - iogateway/PlainTextMessageIOGateway.cpp now works. While not used by muscled, this class can be used by other programs for easy communication with servers that speak ASCII text (e.g. web servers, XML server, e-commerce servers, etc). See PlainTextMessageIOGateway.h for details. - Added test/plaintextclient.cpp and test/portableplaintext.cpp. These are command line communications test programs, similar to testreflectlient.cpp and portablereflectclient.cpp, respectively, but using plain text streams rather than flattened PortableMessages. - Added a Shutdown() method to the PortableDataIO classes. This method can be used to immediately close the underlying socket/file descriptor/whatever, without having to delete the PortableDataIO object. - Made AbstractMessageIOGateway::GetDataIO() public. - BecomeDaemonProcess() now takes two optional arguments: the first indicates where to redirect stderr and stdout to. Default value is "/dev/null". The second indicates whether or not to try and create a file if it can't be opened; default is false. * When the MessageTransceiverThread gets an I/O error, it now closes its connection immediately (by calling GetDataIO()->Shutdown()) rather than waiting for the user to do it. * The muscled ServerProcessLoop() and MessageTransceiverThread now both suppress SIGPIPE signals, as these can be raised when sending to a remotely-closed socket, killing the thread. v1.62 - Released 3/2/2001 - Added a PR_NAME_SERVER_VERSION parameter to the parameter set returned by the server. This field contains a string to indicate the version of MUSCLE the muscled server was compiled from. (Currently the string is "1.62") * Several parameter name constants were missing from StorageReflectConstants.java. Added. * The clever byte-swapping macros put in for MacOS/X were screwing up the byte-ordering for Linux, so I removed them. * PortableMessage.java had a call to Vector.add() in it. Changed it to Vector.addElement(). * Made the _empty Hashtable in PortableMessage.java demand allocated, otherwise IE would barf on it. v1.61 - Released 2/16/2001 - Changed the Pulse()/GetPulseTime() callbacks to use uint64s instead of timeval structs--uint64's are much easier to use than timevals. - Added a BecomeDaemonProcess() function to NetworkUtilityFunctions.h This function calls fork() and all the other incantations necessary to convert the current process into a canonical Posix daemon task. - muscled now recognizes the parameter 'daemon'. If specified, muscled will detach from the shell and run as a background/daemon task. * muscled now parses keywords even if they have no '=' sign/value specified. * Changed the SysLog implementation to use separate callbacks for console and file logging. Before it was using the same callback for both, but certain versions of Linux crash if I try to re-use a va_list object. v1.60 - Released 2/1/2001 - Added Java client support to MUSCLE! (See README-JAVA.txt) - Changed header comments to JavaDoc style throughout. - Added extra commenting to a lot of previously uncommented header code. Now all public and protected methods and member items are documented. - The muscle/html/autodoc/genDocs.sh script now calls doxygen instead of PERCEPS. Doxygen is a very nice autodocumenting program, and a BeOS port can be found on BeBits. - Added a muscle.dox config file to the muscle/html/autodoc directory. - Added a () operator to the PortableString class so you can say myString(), instead of myString.Cstr(), if you want. - PortableString methods StartsWith, EndsWith(), EndsWithIgnoreCase(), and StartsWithIgnoreCase() now return bool instead of int. - The PR_RESULT_PARAMETERS messages returned by the server now include uint64 PR_NAME_SERVER_MEM_AVAILABLE, PR_NAME_SERVER_MEM_USED, and PR_NAME_SERVER_MEM_MAX fields that indicates how much memory the server has available to be allocated by all MUSCLE clients. - Added a FileDescriptorDataIO class to the dataio directory. This dataio supports sessions that want to do read() and write() on a file descriptor for their I/O. * AddFlat(), PrependFlat(), ReplaceFlat(), and FindFlat() will now call their Point, String, or Message counterparts if they are passed a PortablePoint, PortableString, or PortableMessage object. * Flattened objects added to a PortableMessage are now filed using the field type returned by their TypeCode() member, rather than always as B_OBJECT_TYPE. This will break compatibility with old clients that expected B_OBJECT_TYPE flattened objects; sorry about that. * Added in some extra tweaks so that MUSCLE will compile under MacOS/X. * A bunch of member variables of the AbstractMessageIOGateway class were protected when they should have been private. Changed them to private and added protected accessor methods where necessary. * HTML-ized the README.TXT file (now named README.html) v1.51 - Released 1/3/2001 - Added PR_COMMAND_KICK, PR_COMMAND_ADDBANS, and PR_COMMAND_REMOVEBANS commands. Messages of these types instruct the muscle server to disconnect other clients, forbid IP addresses from connecting to the server, and remove previously added bans, respectively. These messages will only be honored if sent by a privileged client; otherwise a PR_RESULT_ERRORACCESSDENIED message is returned. - muscled now takes "privban=", "privunban=", "privkick=", and "privall=" arguments, to specify which clients are allowed to do kick, ban, or unban ops. (if not specified, no clients will be privileged) - Added an 'admin' command-line tool to the muscle/server directory that lets you manage your server's ban lists and/or kick users without having to restart the server. Run 'admin help' for args. - Made ReflectServer::GetCentralState() public. * Removed the ClientConnected() and SetClientConnected() callbacks in favor of a more elegant StorageReflectSession oriented privileges system. The new system allows the server operator to specify which clients are allowed to kick, ban, and unban other clients. v1.50 - Released 12/29/2000 - Loosened up the flattened-PortableMessage protocol specification a little bit. It is now legal to add fields with arbitrary typecodes to a PortableMessage, and PortableMessages with fields that have arbitrary typecodes may be Unflatten()'d without causing an error. This will allow the addition and use of new datatypes without breaking backwards compatibility, thus avoiding a repeat of the problems that were caused by adding the B_MIME_TYPE support. - support/PortableMacros.h now contains a MUSCLE_VERSION_STRING #define, indicating the current version of MUSCLE. muscled will print this version string out on startup if you set the display threshold to DEBUG or lower. * Tweaked StorageReflectSession.{cpp,h} to get it to compile under Red Hat Linux 7.0. v1.45 - Released 12/22/2000 - Added a GetPeerInfo() function into NetworkUtilityFunctions.{cpp,h}. This function returns the remote host IP and port of a connected socket. - Added a ClientConnected() virtual method and SetClientConnectedCallbackFunc() method to ReflectServer. Both of these mechanisms allow connecting clients to be checked before allowing them access to the server. - muscled can now accept zero or more ban= arguments on the command line. Each ban argument specifies an IP address (or wildcard pattern of IP addresses) to ban from the server. - Added EndServer() methods to the ReflectServer and AbstractReflectSession classes. These allow you to cause muscled to exit in a controlled manner. - You can now disable the memory-usage-tracking overloads of new and delete by defining the preprocessor symbol DISABLE_MUSCLE_MEMORY_TRACKING for ReflectServer.cpp. - muscled's Makefile now supports both optimized and unoptimized builds of muscled. Do "make" for an unoptimized build, or "make optimized" for an optimized build. (Be sure to "make clean" first when switching from one to the other!) * Fixed a couple of memory leaks in the PortableHashtable class. * Rewrote PortableHashtable::GrowTable() to handle out-of-memory conditions correctly. * Removed the WATCH_MUSCLE_MEMORY_USAGE macros, since the overloaded new and delete operators do the same thing in a more elegant way. * Updated the docs slightly to reflect the fact that level one server-database nodes are named after the clients' IP addresses, not their hostnames. * Fixed an uninitialized-pointer problem that could make muscled crash while denying a login. v1.44 - Released 12/21/2000 - Modified PortableHashtable to maintain a linked list of PortableHashtableEntry objects. This should speed up traversals somewhat, as the PortableHashtableIterator no longer needs to iterate over the empty portions of the table. - Merged in Trey Boudreau's changes to support adding fields of type B_MIME_TYPE to a PortableMessage. - Added IndexOfIgnoreCase() and LastIndexOfIgnoreCase() methods to PortableString that take chars instead of (const char *)'s as their second argument. v1.43 - Released 12/01/2000 - Added a "Custom Servers.html" file to muscle/html. This file contains information on making your own custom MUSCLE server. - Changed ObjectPool to reuse items in LIFO order rather than FIFO. This may increase cache coherency in some cases. - Makefile now compiles muscled with -O3 and -fomit-frame-pointer options under gcc, for efficiency. - Added SetMessageFlattenCallback() and SetMessageUnflattenCallback() methods to the PortableMessageIOGateway class (for when you can't be bothered to do proper subclassing ;^)) - Added ParseLogLevelToken() function to SysLog.h, and added 'display' and 'log' arguments to muscled, so that you can specify how what sort of output you want on the command line. (e.g. "./muscled display=debug log=none") - Added more *IgnoreCase() methods to PortableString, and changed PortableString::Equals() to return a bool instead of an int. - Pulled the timeval utility functions out of NetworkUtilityFunctions.{cpp,h} and into their own file, netutil/TimeUtilityFunctions.h Also declared them all inline, so you don't need to link anything extra in to use them. - Moved references to into PortableTypeDefs.h, and added a #include there so that including this header can be avoided. (This is to support certain embedded architectures which don't seem have this file...) - Added a operator() overload to the PortableRefCount(), so you can now specify myRef() instead of myRef.GetItemPointer(). * Renamed the LOG_* constants in SysLog.h to MUSCLE_LOG_*, to avoid conflicts with the constants in Be's support/syslog.h header. (This may break some existing code, sorry about that) * Disabled the memory-allocation code under BeOS/PowerPC environments, as it was causing mysterious crashes (possible compiler bug?). This means that if you are running muscled on a PowerPC BeOS machine, the memory allocation limits will be ignored. v1.42 - Released 10/18/2000 - Added a new function, AddOutOfMemoryHandler((void *)()). This lets you install your own handler that will be called in the event of a memory allocation failure. - Added a new command code, PR_COMMAND_PING. When muscled receives a message of this type from its client, changes the message's 'what' code to PR_RESULT_PONG, and sends the message right back to the client. - Added a GetRemainderOfString() method to the StringTokenizer class. * Moved the StorageReflectSession::DrainPools() call out of ReflectServer.cpp, and into a callback that is installed by muscled.cpp. This allows custom servers to be compiled without having to link in StorageReflectSession.o. * The memory-tracking new and delete operators now count their own 4-byte-per-allocation overhead in the allocated-memory total. v1.41 - Released 10/8/2000 - Added a FindDataPointer() method to the PortableMessage class. This method returns a writable pointer to a field's data array, for efficiency. - PortableMessage::AddData() now allows the (data) parameter to be NULL. If (data) is NULL, default-constructed objects or uninitialized data bytes will be added to the PortableMessage. - PortableMessage::FindData() and FindDataPointer() now allow the (numBytes) parameter to be NULL. - muscled now parses command line arguments of the form keyword=value. Currently supported keywords are 'port', 'help', and 'maxmem'. - muscled now detects out-of-memory situations and tries to free up some memory by draining the object pools and/or forcibly disconnecting the active session when an out-of-memory error occurs. - muscled now lets you specify the maximum number of bytes of data it should allow itself to have allocated at any one time. For example, entering "muscled maxmem=15" will cause muscled to not help itself to more than 15 megabytes of memory. * Went through the code and made it more resistant to crashing in out-of-memory situations. (i.e. it should correctly handle NULL being returned by new (nothrow) in all cases) * Fixed a bug that would cause muscled to crash if it was sent a malformed PortableMessage. Thanks to Ben and Pete for helping me find this bug! * Now compiles cleanly with full warnings enabled, thanks to Christopher Tate. v1.40 - Released 9/8/2000 - Added ordered-child-indexing to StorageReflectSession. Support for this includes the new PR_COMMAND_INSERTORDEREDDATA code, the PR_RESULT_INDEXUPDATED result code, and the INDEX_OP_* enums. (see comments in StorageReflectConstants.h and the new chapter at the end of the Beginner's Guide for details) - Added Prepend*() methods to the PortableMessage class. - PortableQueue and PortableString can now handle very small strings/lists without having to do any dynamic memory allocation. - Added Head(), Tail(), HeadPointer(), TailPointer(), and InsertItemAt() to PortableQueue. v1.31 - Released 7/30/2000 - Added custom-callback capability to the SysLog module. (AddLogCallback(), RemoveLogCallback()) - Added the OnceEvery() function to NetworkUtilityFunctions. * Fixed an uninitialized timeval struct in AbstractMessageIOGateway-- this was causing muscled to panic and exit sometimes under FreeBSD. (Thanks to Peter Schultz for helping track down this bug!) v1.30 - Released 6/30/2000 - Added optional object-allocation tracking into the code. This tracking is useful for hunting down memory leaks; to enable it uncomment the -DMUSCLE_WATCH_MEM_USAGE line in the Makefile and recompile the server (from scratch). With this flag enabled, the server will print out memory-allocation stats every so many seconds. - Added some PR_COMMAND_RESERVED and PR_RESULT_RESERVED constants to StorageReflectConstants.h to allow future expansion. - Added a PR_RESULT_ERRORUNIMPLEMENTED code. This message is sent back to the client when the client sends a PR_COMMAND_RESERVED code that the serverd doesn't understand. - Added a PR_COMMAND_JETTISONRESULTS command. When the server receives a message of this type, it will match the paths given in PR_NAME_KEYS against the items in its list of outgoing PR_RESULTS_DATAITEMS messages, and any matched items will be deleted and not sent. If no PR_NAME_KEYS field is found in the PR_COMMAND_JETTISONRESULTS message, then all pending PR_RESULTS_DATAITEMS messages will be dumped. (This is useful when a client is receiving a large result set and decides in the middle of the download that he's no longer interested in it) - muscled no longer does a hostname lookup when a client logs in. This speeds up muscled's response time (and frees it from depending on a working nameserver) but it means that nodes in level one of the database tree will look like '127.0.0.1' instead of 'mycomputer.mydomain.com'. - Added ClientConnectionClosed() callback to the AbstractReflectSession class, so that a session can decide whether it wants to stick around after its TCP connection is gone. - Replaced the AbstractReflectSession class's GetIncomingMessageQueue() and GetOutgoingMessageQueue() methods with the more flexible GetGateway() and SetGateway() methods. - Added some utility functions to StringMatcher.{cpp,h}: IsRegexToken(), HasRegexTokens(), and MakeRegexCaseInsensitive(). - Now compiles under FreeBSD4.0, using gmake. * The StringMatcher wasn't handling parentheses properly. Fixed it, so now you can use expressions like *.(jpg,mp?). Also rewrote the regex translation code to be more readable, and fixed a nasty dangling-pointer bug in the process. * Changed the RefCountMem class to use atomic_add instead of the C preincrement and predecrement operators, so that it can be used safely in multithreaded environments. * Fixed a subtle bug in the Remove*() methods of the PortableQueue class that could cause crashes if you were removing items whose assignment operators looked at the PortableQueue they were being removed from... geez * Added some missing virtual destructors * Rewrote the PortableString class to be more efficient, and in the process found and fixed a nasty bug--the CStringHashFunc() was completely broken. * StringMatcher::Match() is now tagged as const. v1.24 - 6/17/2000 - muscled now splits its PR_RESULT_DATAITEMS messages into multiple messages if the message has more than 50 items in it. This allows for more fine-grained updates. - Added a PR_NAME_MAX_UPDATE_MESSAGE_ITEMS parameter that can be set by the client to change the above threshold if desired. v1.23 - 6/15/2000 - Added a StartServerThread() method to the MessageTransceiverThread class. Now the MessageTransceiverThread can be used to accept multiple overlapping connections, instead of just a series of single connections. * make clean now removes .xSYM files. v1.22 - 6/14/2000 * MessageTransceiverThread::WaitForAllMessagesToBeSent() was broken. Changed it to use benaphores instead of BLockers, and now all is well. v1.21 - 6/12/2000 - Added Prepend() and Append() methods to PortableString. - Added InetNtoA() convenience method to NetworkUtilityFunctions.cpp - Added EscapeRegexTokens() to StorageReflectUtils.h * User messages would be reflected back to the sender even when the reflect-to-self flag wasn't set. Fixed. * Fixed several bugs in the MessageTransceiverThread class. * muscled now handles connections from localhost correctly. v1.20 - 6/8/2000 - Added new accessors to PortableHashtable and PortableMessage that return key and value objects by pointer rather than by value. This can make access and traversals more efficient, as it eliminates an unnecessary data copy. - Added default constructors to the PortableHashtableIterator and PortableMessageFieldNameIterator classes so that you can use them in arrays, as class members, etc. - Added SetOutgoingQueueDrainedMessage() to the MessageTransceiverThread API so that you can (optionally) receive notification when the outgoing message queue has become empty. * Made ObjectPool's destructor virtual. v1.10 - 6/1/2000 - Added ReplaceSession() method, by which a server-side session object can replace itself with a different one. - AbstractMessageIOGateway objects can now request Pulse() callbacks. - Added system logging, to the console or to a log file, or both. * Fixed some minor compilation problems v1.01 - 4/11/2000 o Redesigned the Pulse() support to work based on absolute wakeup times rather than relative periods. - Added some convenience methods for working with timeval structs to NetworkUtilityFunctions.h v1.00 - 3/29/2000 - Initial release