Skip to content

Commit

Permalink
v6.83 release
Browse files Browse the repository at this point in the history
  • Loading branch information
jfriesne committed May 3, 2018
1 parent 015528b commit 0708b1f
Show file tree
Hide file tree
Showing 134 changed files with 17,381 additions and 167 deletions.
24 changes: 24 additions & 0 deletions HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@ key: - new feature
* bug fixed
o other

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 tests/Makefile-mt no longer tries to compile testreflectsession
except when executing on an OS that testreflectsession supports.
Expand Down
2 changes: 1 addition & 1 deletion README.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<H2>
MUSCLE: Crossbar Server, Portable Messaging and Support Classes<p>
4/25/2018 v6.82 jaf@meyersound.com<p>
5/3/2018 v6.83 jaf@meyersound.com<p>
Jeremy Friesner / Meyer Sound Laboratories Inc.<p>
Win32 compatibility contributions by Vitaliy Mikitchenko<p>
C# client code by Wilson Yeung<p>
Expand Down
2 changes: 1 addition & 1 deletion html/Beginners Guide.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<HTML>
<HEAD>
<H1>MUSCLE Overview and Beginner's Guide</H1>
<H4>v6.82 / Jeremy Friesner / Meyer Sound Laboratories Inc (jaf@meyersound.com) 4/25/2018</H4>
<H4>v6.83 / Jeremy Friesner / Meyer Sound Laboratories Inc (jaf@meyersound.com) 5/3/2018</H4>
<A HREF="http://www.lcscanada.com/muscle/html/index.html">Click here for DOxygen class API documentation</A>
</HEAD>

Expand Down
2 changes: 1 addition & 1 deletion html/Custom Servers.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<HTML>
<HEAD>
<H1>Implementing a Custom Server with MUSCLE</H1>
<H4>v6.82 / Jeremy Friesner / Meyer Sound Laboratories Inc / jaf@meyersound.com 4/25/2018</H4>
<H4>v6.83 / Jeremy Friesner / Meyer Sound Laboratories Inc / jaf@meyersound.com 5/3/2018</H4>
</HEAD>
<BODY bgcolor=#ffffff>
<H2>Introduction</H2>
Expand Down
8 changes: 5 additions & 3 deletions html/muscle-by-example/README.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ cd into the muscle/html/muscle-by-example/examples/* folders and enter "make" to
compile the programs, then run them from the command line (e.g. "./example_1_basic_usage",
etc).

Note that while the MUSCLE toy programs can be compiled under any OS, the Makefiles that
are included to compile them will work only under Linux and MacOS/X, for now -- Windows
users are on their own for the time being.
The MUSCLE toy programs can be compiled under any popular OS. The Makefiles that
are included to compile them will work under Linux and MacOS/X (and possibly
other POSIX-y OS's too) -- if you want to compile under Windows, use Visual
Studio 2015 (or later) and the project files in the examples\vc++14
sub-directory, instead.

If you'd like to generate your own HTML from the Markdown files in the "docs" folder,
you can do so by installing the MkDocs python package (per the instructions at
Expand Down
2 changes: 1 addition & 1 deletion html/muscle-by-example/docs/atomiccounter.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
A Thread-safe, lockless int32-counter

* Similar to: `std::atomic<int32>`, `InterlockedIncrement()/InterlockedDecrement()`, `OSAtomicIncrement32Barrier()/OSAtomicDecrement32Barrier()`
* Used primarily by the [Ref](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1Ref.html)/[RefCountable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1RefCountable.html) classes for implementing thread-safe shared pointers
* Used primarily by the [Ref](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Ref.html)/[RefCountable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1RefCountable.html) classes for implementing thread-safe shared pointers
* Constructor initializes the counter to zero
* [AtomicIncrement()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1AtomicCounter.html#abfaf1ffb8afea7f355c71680fb35a693) does an atomic-increment of the counter value, and returns true iff the counter's post-increment value is 1.
* [AtomicDecrement()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1AtomicCounter.html#a912a1e8990ab05b13ad4934b91ecc00b) does an atomic-decrement of the counter value, and returns true iff the counter's post-decrement value is 0.
Expand Down
14 changes: 7 additions & 7 deletions html/muscle-by-example/docs/hashtable.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
Templated container class `Hashtable<Key,Value>` is a hash-based dictionary class that also maintains a consistent, user-specifiable iteration order.

* Similar to: `std::map<K,V>`, and `std::unordered_map<K,V>` (combined!), `java.util.Hashtable`, `QHash`, etc.
* O(1) [Get()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a19543125698485a668ce2cc53c8c057d)/[ContainsKey()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a790ed182d252511a38574a741953ccbd)/[Put()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableMid.html#a59691a7665446505535cf02aadfdebf3)/[Remove()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#aacb659ec030127644ef076f0f70d6f92)
* O(1) [RemoveFirst()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a2f3bac865a3ffbeaeb6f63117d9a76b4)/[RemoveLast()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a9236392a40ab749ece15edb5bf1f6d3d)
* O(N*log(N)) [SortByKey()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#aed9bd2abb05b26914a83735bed57c3e3)
* O(N*log(N)) [SortByValue()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a9fc3e1a503a8889a0cacb6ed1ef7f9ec)
* O(1) [MoveToFront()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a4216f4cb9567bb38ab4e42f546b4e3a8)/[MoveToBack()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#ade6408ab7e42d5dcd2b9924910c2d528)/[MoveToBefore()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a71e3c5d80457fd0e59fb5cc5e1eb72c2)/[MoveToBehind()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#a3c2935ce21a8855d3128b79c52ece19d)
* O(1) [SwapContents()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableBase.html#ace1d892c10980ad4c1f6fd44ca953bd2)
* O(1) [Get()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a19543125698485a668ce2cc53c8c057d)/[ContainsKey()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a790ed182d252511a38574a741953ccbd)/[Put()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableMid.html#a59691a7665446505535cf02aadfdebf3)/[Remove()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#aacb659ec030127644ef076f0f70d6f92)
* O(1) [RemoveFirst()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a2f3bac865a3ffbeaeb6f63117d9a76b4)/[RemoveLast()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a9236392a40ab749ece15edb5bf1f6d3d)
* O(N*log(N)) [SortByKey()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#aed9bd2abb05b26914a83735bed57c3e3)
* O(N*log(N)) [SortByValue()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a9fc3e1a503a8889a0cacb6ed1ef7f9ec)
* O(1) [MoveToFront()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a4216f4cb9567bb38ab4e42f546b4e3a8)/[MoveToBack()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#ade6408ab7e42d5dcd2b9924910c2d528)/[MoveToBefore()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a71e3c5d80457fd0e59fb5cc5e1eb72c2)/[MoveToBehind()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableBase.html#a3c2935ce21a8855d3128b79c52ece19d)
* O(1) [SwapContents()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Hashtable.html#a40d409c769d9ada96a45b3bfcca39481)
* Iteration of key/value pairs is done via [HashtableIterator](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableIterator.html) class
* Addresses of key and value objects never change (except when the [Hashtable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Hashtable.html)'s internal array is reallocated)
* No heap allocations/deletions during use (except when the [Hashtable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Hashtable.html)'s internal array is reallocated)
* If you know how many key/value pairs you need to store, you can (optionally) call [EnsureSize()](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1HashtableMid.html#a7a96b0de767c2bc01e0d86686c54545d) up-front to avoid unnecessary array-reallocations while adding data.
* If you know how many key/value pairs you need to store, you can (optionally) call [EnsureSize()](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableMid.html#a7a96b0de767c2bc01e0d86686c54545d) up-front to avoid unnecessary array-reallocations while adding data.
* It's okay to modify or delete the [Hashtable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Hashtable.html) during an iteration -- any active [HashtableIterator](https://public.msli.com/lcs/muscle/html/classmuscle_1_1HashtableIterator.html)(s) will handle the modification gracefully.
* Unlike many other hash table implementations, all [Hashtable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Hashtable.html) operations remain fully efficient even when the table is at 100% load-factor -- so there's no need to reallocate the underlying array until it has become completely full.

Expand Down
6 changes: 3 additions & 3 deletions html/muscle-by-example/docs/refcount.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Reference-counting for heap-allocated objects, to makes memory-leaks and use-aft

* Similar to: `std::shared_ptr<T>`, `boost::intrusive_ptr<T>`, `QSharedPointer`
* Object to be reference-counted must be a subclass of [RefCountable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1RefCountable.html).
* The ref-counted object will always be deleted by the destructor of the last [Ref](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1Ref.html) that points to it -- explicitly calling `delete` is NEVER necessary!
* The ref-counted object will always be deleted by the destructor of the last [Ref](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Ref.html) that points to it -- explicitly calling `delete` is NEVER necessary!
* Often used in conjunction with the [ObjectPool](https://public.msli.com/lcs/muscle/html/classmuscle_1_1ObjectPool.html) class to recycle used objects (to minimize heap allocations/deallocations)
* Idiom: For any [RefCountable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1RefCountable.html) class `FooBar`, the [DECLARE_REFTYPES()](https://public.msli.com/lcs/muscle/html/RefCount_8h.html#a5f9b4b0acbe24ff62f3cfddaa4b01d88) macro defines typedefs `FooBarRef` and `ConstFooBarRef`:

Expand All @@ -22,8 +22,8 @@ Reference-counting for heap-allocated objects, to makes memory-leaks and use-aft
twoRef()->Hello(); // () operator gives pointer to RefCountable object
```
* [Ref](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1Ref.html) is similar to a read/write shared-pointer, [ConstRef](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1ConstRef.html) is similar to a read-only shared-pointer.
* [RefCountable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1RefCountable.html) uses an [AtomicCounter](https://public.msli.com/lcs/muscle/html/classmuscle_1_1AtomicCounter.html) internally for its ref-count, and [ObjectPools](https://public.msli.com/lcs/muscle/html/classmuscle_1_1ObjectPool.html) are thread-safe, so it's safe to pass [Ref](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1Ref.html) and [ConstRef](https://public.msli.com/lcs/muscle/html/singletonmuscle_1_1ConstRef.html) objects around to different threads.
* [Ref](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Ref.html) is similar to a read/write shared-pointer, [ConstRef](https://public.msli.com/lcs/muscle/html/classmuscle_1_1ConstRef.html) is similar to a read-only shared-pointer.
* [RefCountable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1RefCountable.html) uses an [AtomicCounter](https://public.msli.com/lcs/muscle/html/classmuscle_1_1AtomicCounter.html) internally for its ref-count, and [ObjectPools](https://public.msli.com/lcs/muscle/html/classmuscle_1_1ObjectPool.html) are thread-safe, so it's safe to pass [Ref](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Ref.html) and [ConstRef](https://public.msli.com/lcs/muscle/html/classmuscle_1_1ConstRef.html) objects around to different threads.

Try compiling and running the mini-example-programs in `muscle/html/muscle-by-example/examples/refcount` (enter `make` to compile example_*, and then run each from Terminal while looking at the corresponding .cpp file)

Expand Down
2 changes: 1 addition & 1 deletion html/muscle-by-example/docs/srscommandmessages.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ myMessageTransceiverThread.SendMessageToSessions(getPMsg);
- Read-only parameters (that were set by the server) cannot be deleted.
- Here is an example invocation:
<pre>
MessageRef delPMsg = GetMessageFromPool(PR_COMMAND_GETPARAMETERS);
MessageRef delPMsg = GetMessageFromPool(PR_COMMAND_REMOVEPARAMETERS);
delPMsg()->AddString(PR_NAME_KEYS, "SUBSCRIBE:/\\\*/\\\*/node\\\*"); // cancel one specific subscription
delPMsg()->AddString(PR_NAME_KEYS, "SUBSCRIBE:\*"); // cancel all my subscriptions!
myMessageTransceiverThread.SendMessageToSessions(delPMsg);
Expand Down
20 changes: 15 additions & 5 deletions html/muscle-by-example/docs/srsreplymessages.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ This is a partial list -- the full list of result codes can be seen [here](https
- An example of how a client might parse a [Message](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Message.html) of this type follows:

<pre>
// This table holds the child-node-names-in-index-order list for each ordered-index-node
Hashtable<String, Queue<String> > indices; // nodepath -> index
// This table holds the child-node-names-in-index-order list for each
// ordered-index-node that the client is subscribed to
Hashtable&lt;String, Queue&lt;String&gt; &gt; indices; // nodepath -> index

void ParseIncomingIndexUpdatedMessage(const MessageRef & msg)
{
Expand All @@ -72,15 +73,24 @@ This is a partial list -- the full list of result codes can be seen [here](https
switch(nextInstruction()->Cstr()[0])
{
case INDEX_OP_CLEARED: // a.k.a 'c'
indices.Remove(parentNodePath);
(void) indices.Remove(parentNodePath);
break;

case INDEX_OP_ENTRYINSERTED: // a.k.a 'i'
indices.GetOrPut(parentNodePath)->InsertItemAt(pos, childName);
{
Queue&lt;String&gt; * idx = indices.GetOrPut(parentNodePath);
if (idx) (void) idx->InsertItemAt(pos, childName);
}
break;

case INDEX_OP_ENTRYREMOVED: // a.k.a 'r'
indices.GetOrPut(parentNodePath)->RemoveItemAt(pos);
{
Queue&lt;String&gt; * idx = indices.GetOrPut(parentNodePath);
if ((idx)&&(idx->RemoveItemAt(pos) == B_NO_ERROR)&&(idx->IsEmpty()))
{
(void) indices.Remove(parentNodePath);
}
}
break;
}
}
Expand Down
9 changes: 9 additions & 0 deletions html/muscle-by-example/docs/void.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# muscle::Void class [(API)](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Void.html)

```#include "util/Hashtable.h"```

A [Void](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Void.html) is a minimal dummy-object with no data or methods.

* Its primary use is to serve as a "placeholder" value-type in a [Hashtable](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Void.html) that needs only to keep keys and not values.
* Every [Void](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Void.html) object is equal to every other [Void](https://public.msli.com/lcs/muscle/html/classmuscle_1_1Void.html) object.

2 changes: 1 addition & 1 deletion html/muscle-by-example/examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
TOPTARGETS := all clean

SUBDIRS := $(wildcard */.)
SUBDIRS := $(dir $(wildcard */Makefile))

$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS): libmuscle.a
Expand Down
25 changes: 18 additions & 7 deletions html/muscle-by-example/examples/README.TXT
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
This folder contains the "toy example" programs for the "MUSCLE by Example" self-guided tour.

To compile them, you can either compile them all at once by typing "make" while in this folder,
or you can cd to the individual sub-directory you are interested in and enter "make" from there,
if you'd prefer just to compile the examples in that directory.
MacOS/X and Linux users:

Note that these programs are known to work under MacOS/X and Linux; they should (in principle)
work under Windows as well, but you'll need to find your own way to compile them there since
the Makefiles provided are for gmake and do not (AFAIK) work under Windows.
To compile the examples, you can either compile them all at once by typing "make" while in this
folder, or you can cd to the individual sub-directory you are interested in and enter "make" from
there, if you'd prefer just to compile the examples in that directory.

-Jeremy
Windows users:

Assuming your have Visual Studio 2015 (or later) installed, you can compile
the all of the examples from the DOS prompt by cd'ing into the vc++14
sub-directory and entering this command:

BUILD_ALL.bat

... or alternatively you can open VisualStudio and compile the following
.sln files (in the listed order!) from the GUI:

muscle\vc++14\muscle.sln
muscle\html\muscle-by-example\examples\vc++14\MuscleByExample.sln

-Jeremy
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ int main(int argc, char ** argv)

PrintExampleDescription();

#ifdef MUSCLE_AVOID_CPLUSPLUS11
Queue<String> childArgv; (void) childArgv.AddTail("./example_2_tcp_server"); // support for pre-C++11 compilers
#else
Queue<String> childArgv = {"./example_2_tcp_server"};
#endif
ChildProcessDataIO cpIO(false); // false == non-blocking
if (cpIO.LaunchChildProcess(childArgv) != B_NO_ERROR)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class MyLogCallback : public LogCallback
virtual void Log(const LogCallbackArgs & a)
{
char temp[1024];
vsprintf(temp, a.GetText(), *a.GetArgList());
vsnprintf(temp, sizeof(temp), a.GetText(), *a.GetArgList());

fprintf(stderr, "MyLogCallback::Log(): Got a severity-%i callback for text [%s]\n", a.GetLogLevel(), temp);
}
Expand All @@ -46,7 +46,7 @@ class MyLogLineCallback : public LogLineCallback
virtual void LogLine(const LogCallbackArgs & a)
{
char temp[1024];
vsprintf(temp, a.GetText(), *a.GetArgList());
vsnprintf(temp, sizeof(temp), a.GetText(), *a.GetArgList());

fprintf(stderr, "MyLogLineCallback::LogLine(): Got a severity-%i callback for text [%s]\n", a.GetLogLevel(), temp);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ int main(int argc, char ** argv)
printf("Here is the Message we are going to save as an ASCII text file:\n");
myConfig.PrintToStream();

#ifdef WIN32
FILE * fpOut = NULL;
(void)fopen_s(&fpOut, "test_config.txt", "w"); // Why MSVC thinks this is more secure than fopen() is beyond me
#else
FILE * fpOut = fopen("test_config.txt", "w");
#endif
if (fpOut == NULL)
{
printf("Error, couldn't open test_config.txt for writing!\n");
Expand Down Expand Up @@ -78,7 +83,12 @@ int main(int argc, char ** argv)
printf("\n");
printf("Now let's see if we can read the text file back into RAM as a Message again:\n");

#ifdef WIN32
FILE * fpIn = NULL;
(void)fopen_s(&fpIn, "test_config.txt", "r"); // why MSVC2015 thinks this is more secure than fopen() is beyond me
#else
FILE * fpIn = fopen("test_config.txt", "r");
#endif
if (fpIn == NULL)
{
printf("Error, couldn't open test_config.txt for reading!\n");
Expand Down
Loading

0 comments on commit 0708b1f

Please sign in to comment.