<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.visual-prolog.com/index.php?action=history&amp;feed=atom&amp;title=Master%2Fslave_processes</id>
	<title>Master/slave processes - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.visual-prolog.com/index.php?action=history&amp;feed=atom&amp;title=Master%2Fslave_processes"/>
	<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;action=history"/>
	<updated>2026-04-11T12:06:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4968&amp;oldid=prev</id>
		<title>Thomas Linder Puls: review</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4968&amp;oldid=prev"/>
		<updated>2024-10-15T11:32:21Z</updated>

		<summary type="html">&lt;p&gt;review&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:32, 15 October 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l21&quot;&gt;Line 21:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 21:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;All methods are asynchronous (using an &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; as execution context), so {{lang|Suspending Predicates|suspending predicates}} must be applied.  And synchronization to non-threadsafe structures must be used.  &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; will have to be used to switch execution context to the GUI thread for GUI operations (and in many applications for safe access to program state).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;All methods are asynchronous (using an &amp;lt;vp&amp;gt;executionContext_pool&amp;lt;/vp&amp;gt; as execution context), so {{lang|Suspending Predicates|suspending predicates}} must be applied.  And synchronization to non-threadsafe structures must be used.  &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; will have to be used to switch execution context to the GUI thread for GUI operations (and in many applications for safe access to program state).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The master/slave process concept is illustrated by &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;an &lt;/del&gt;demo project.  In the demo project the master is a builder similar to the &amp;#039;&amp;#039;&amp;#039;vipBuilder&amp;#039;&amp;#039;&amp;#039;. This master spawns a number of compiler/slave processes.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The master/slave process concept is illustrated by &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;a &lt;/ins&gt;demo project.  In the demo project the master is a builder similar to the &amp;#039;&amp;#039;&amp;#039;vipBuilder&amp;#039;&amp;#039;&amp;#039;. This master spawns a number of compiler/slave processes.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The demo is academic in the sense that nothing is really build; the &amp;quot;compilers&amp;quot; merely simulate that they do something.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The demo is academic in the sense that nothing is really build; the &amp;quot;compilers&amp;quot; merely simulate that they do something.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Notice that the demo program uses the name space &amp;lt;vp&amp;gt;compiler_ms&amp;lt;/vp&amp;gt; for interfaces and classes used in the process interface.  &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Fir &lt;/del&gt;simplicity the name space declarations are not included in this article.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Notice that the demo program uses the name space &amp;lt;vp&amp;gt;compiler_ms&amp;lt;/vp&amp;gt; for interfaces and classes used in the process interface.  &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;For &lt;/ins&gt;simplicity the name space declarations are not included in this article.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The compiler/slave has this interface:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The compiler/slave has this interface:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l50&quot;&gt;Line 50:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 50:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;We will consider the details of this interface below, currently the interesting thing is that it defines procedures &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt;.  Notice that they are {{lang|Suspending Predicates|suspending predicates}}.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;We will consider the details of this interface below, currently the interesting thing is that it defines procedures &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt;.  Notice that they are {{lang|Suspending Predicates|suspending predicates}}.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;When the master spawn this slave it will call the setSettings to inform the slave about settings (i.e. corresponding to the command line flags , etc of a regular compiler). And then it will call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; on a file and when that operation completes it will (potentially) call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; again on another file.  The master will continue this until there are no more files to compile and then it will terminate the slave.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;When the master spawn this slave it will call the &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;vp&amp;gt;&lt;/ins&gt;setSettings&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/vp&amp;gt; &lt;/ins&gt;to inform the slave about settings (i.e. corresponding to the command line flags , etc of a regular compiler). And then it will call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; on a file and when that operation completes it will (potentially) call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; again on another file.  The master will continue this until there are no more files to compile and then it will terminate the slave.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Actually, the master will spawn a number of slaves, so that several files can be compiled in parallel.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Actually, the master will spawn a number of slaves, so that several files can be compiled in parallel.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Likewise the &lt;/del&gt;master has this interface &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;(&lt;/del&gt;towards the slave&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;)&lt;/del&gt;:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;The &lt;/ins&gt;master has this interface towards the slave:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;vip&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;vip&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l107&quot;&gt;Line 107:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 107:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/vip&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/vip&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;It supports the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface (which is the main proxy facility).  It also supports &amp;lt;vp&amp;gt;useExe&amp;lt;/vp&amp;gt; which is the PFC standard interface for subprocesses and finally &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;is has a standard extra predicate to request the termination of the subprocess.  Finally, &lt;/del&gt;it also contains the predicate &amp;lt;vp&amp;gt;terminate_toRemote&amp;lt;/vp&amp;gt; which is used internally to terminate the slave process.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;It supports the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface (which is the main proxy facility).  It also supports &amp;lt;vp&amp;gt;useExe&amp;lt;/vp&amp;gt; which is the PFC standard interface for subprocesses and finally it also contains the predicate &amp;lt;vp&amp;gt;terminate_toRemote&amp;lt;/vp&amp;gt; which is used internally to terminate the slave process.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The class declaration of the &amp;lt;vp&amp;gt;slaveProcess&amp;lt;/vp&amp;gt; looks like this:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The class declaration of the &amp;lt;vp&amp;gt;slaveProcess&amp;lt;/vp&amp;gt; looks like this:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4919&amp;oldid=prev</id>
		<title>Thomas Linder Puls: Released</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4919&amp;oldid=prev"/>
		<updated>2024-01-11T12:01:35Z</updated>

		<summary type="html">&lt;p&gt;Released&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:01, 11 January 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{Template:NonReleased}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The PFC master/slave process concept can be used for a number of reasons:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The PFC master/slave process concept can be used for a number of reasons:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4903&amp;oldid=prev</id>
		<title>Thomas Linder Puls: suspending predicates (vip 11)</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4903&amp;oldid=prev"/>
		<updated>2024-01-08T12:32:46Z</updated>

		<summary type="html">&lt;p&gt;suspending predicates (vip 11)&lt;/p&gt;
&lt;a href=&quot;https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;amp;diff=4903&amp;amp;oldid=4808&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4808&amp;oldid=prev</id>
		<title>Thomas Linder Puls: release</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4808&amp;oldid=prev"/>
		<updated>2021-04-15T13:49:58Z</updated>

		<summary type="html">&lt;p&gt;release&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:49, 15 April 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{NonReleased}}&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The PFC master/slave process concept can be used for a number of reasons:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The PFC master/slave process concept can be used for a number of reasons:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4777&amp;oldid=prev</id>
		<title>Thomas Linder Puls: Thomas Linder Puls moved page Master/Slave processes to Master/slave processes: casing</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4777&amp;oldid=prev"/>
		<updated>2021-04-14T08:18:18Z</updated>

		<summary type="html">&lt;p&gt;Thomas Linder Puls moved page &lt;a href=&quot;/index.php?title=Master/Slave_processes&quot; class=&quot;mw-redirect&quot; title=&quot;Master/Slave processes&quot;&gt;Master/Slave processes&lt;/a&gt; to &lt;a href=&quot;/index.php?title=Master/slave_processes&quot; title=&quot;Master/slave processes&quot;&gt;Master/slave processes&lt;/a&gt;: casing&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 10:18, 14 April 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4774&amp;oldid=prev</id>
		<title>Thomas Linder Puls: init</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Master/slave_processes&amp;diff=4774&amp;oldid=prev"/>
		<updated>2021-04-14T08:08:01Z</updated>

		<summary type="html">&lt;p&gt;init&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{NonReleased}}&lt;br /&gt;
&lt;br /&gt;
The PFC master/slave process concept can be used for a number of reasons:&lt;br /&gt;
&lt;br /&gt;
* To make computations in parallel&lt;br /&gt;
* To isolate computations from each other&lt;br /&gt;
* To manage independent subprocesses&lt;br /&gt;
&lt;br /&gt;
=== Master/slave concepts ===&lt;br /&gt;
&lt;br /&gt;
Master/slave processes are organized hierarchically:&lt;br /&gt;
&lt;br /&gt;
* A master process can have several slave processes&lt;br /&gt;
* Each slave process has exactly one master process.&lt;br /&gt;
* A slave process can be master process of other slave processes.&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;master&amp;#039;&amp;#039;&amp;#039; process spawns and owns the &amp;#039;&amp;#039;&amp;#039;slave&amp;#039;&amp;#039;&amp;#039; processes.&lt;br /&gt;
&lt;br /&gt;
A master and slave process can communicate with each other using remote procedure calls and notifications.  All communication is serialized on pipes that are established between the master and the slave.&lt;br /&gt;
&lt;br /&gt;
The communication is (quite) transparent to the programs, in the master process the slave is represented by a proxy object; calls and notifications from the master to the slave is performed by invoking methods on the proxy object.  Likewise the master is represented by a proxy object in the slave and calls and notifications from slave to master is made on the proxy object.&lt;br /&gt;
&lt;br /&gt;
All methods are asynchronous (using a threadpool as execution context), so asynchronous coding style must be applied.  And synchronization to non-threadsafe structures must be used.  &amp;lt;vp&amp;gt;postAction&amp;lt;/vp&amp;gt; will have to be used to switch execution context to the GUI thread for GUI operations (and in  many applications for safe access to program state).&lt;br /&gt;
&lt;br /&gt;
The master/slave process concept is illustrated by an demo project.  In the demo project the master is a builder similar to the IDE and vipBuilder, this master spawns a number of compiler/slave processes.&lt;br /&gt;
&lt;br /&gt;
The demo is academic in the sense that nothing is really build; the &amp;quot;compilers&amp;quot; merely simulate that they do something.&lt;br /&gt;
&lt;br /&gt;
The compiler/slave has this interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface slave&lt;br /&gt;
    open core, pfc\asynchronous\&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    compile_rsp = compile_rsp(integer LineCount, integer Errors, durationValue CompilationTime).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compile : (string Filename, continuation{compile_rsp} OnCompileResult).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    setSettings : (string Settings).&lt;br /&gt;
&lt;br /&gt;
end interface slave&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that in this academic example the interface name is &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt;. In a real program it would be more natural to call it e.g. &amp;lt;vp&amp;gt;compiler_slave&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
We will consider the details of this interface below, currently the interesting thing is that it defines a procedure &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; and a notification &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When the master spawn this slave it will &amp;quot;notify&amp;quot; the slave about settings (i.e. corresponding to the command line flags , etc of a regular compiler). And then it will call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; on a file and when that operation completes it will (potentially) call &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; again on another file.  The master will continue this until there are no more files to compile and then it will terminate the slave.&lt;br /&gt;
&lt;br /&gt;
Actually, the builder will spawn a number of slaves, so that several files can be compiled in parallel.&lt;br /&gt;
&lt;br /&gt;
Likewise the master has this interface (towards the slave):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface master&lt;br /&gt;
&lt;br /&gt;
domains&lt;br /&gt;
    compilerMessage_ntf = compilerMessage_ntf(string File, integer Line, string Message).&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compilerMessage : (compilerMessage_ntf Message).&lt;br /&gt;
&lt;br /&gt;
end interface master&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This interface only contains a single notification &amp;lt;vp&amp;gt;compilerMessage&amp;lt;/vp&amp;gt; through which the compiler can notify the master with messages from the compilation, while the compilation takes place.&lt;br /&gt;
&lt;br /&gt;
There are restrictions on these interfaces:&lt;br /&gt;
&lt;br /&gt;
* They can contain one-input-one-output procedures (in continuation style)&lt;br /&gt;
* They can contain one-input notifications&lt;br /&gt;
* They cannot contain any other kind of predicates&lt;br /&gt;
* The input and output of the procedures and notifications must be serializable&lt;br /&gt;
&lt;br /&gt;
These two interfaces describes the master/slave process interface.&lt;br /&gt;
&lt;br /&gt;
To make the system complete the following things must be implemented:&lt;br /&gt;
&lt;br /&gt;
* A proxy class must be implemented for each of these interfaces&lt;br /&gt;
* The slave must implement the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface&lt;br /&gt;
* The master must implement the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface as a context to the slave proxy&lt;br /&gt;
&lt;br /&gt;
The following is also necessary, but that is handled by PFC classes:&lt;br /&gt;
&lt;br /&gt;
* The subprocess creation&lt;br /&gt;
* The creation of communication pipes&lt;br /&gt;
* The serialization/deserialization, communication and dispatching of data/messages&lt;br /&gt;
&lt;br /&gt;
The implementation of the proxy classes are quite simple:&lt;br /&gt;
&lt;br /&gt;
=== slaveProcess ===&lt;br /&gt;
&lt;br /&gt;
For the master process we will need a proxy representing the slave process, the interface of this proxy looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface slaveProcess supports slave, useExe&lt;br /&gt;
&lt;br /&gt;
predicates from pfc\masterSlaveProcessSupport&lt;br /&gt;
    terminate_toRemote&lt;br /&gt;
&lt;br /&gt;
end interface slaveProcess&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It supports the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface (which is the main proxy facility).  It also supports &amp;lt;vp&amp;gt;useExe&amp;lt;/vp&amp;gt; which is the PFC standard interface for subprocesses and finally is has a standard extra predicate to request the termination of the subprocess.&lt;br /&gt;
&lt;br /&gt;
The class declaration of the &amp;lt;vp&amp;gt;slaveProcess&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class slaveProcess : slaveProcess&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (master Master).&lt;br /&gt;
&lt;br /&gt;
end class slaveProcess&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;Master&amp;lt;/vp&amp;gt; is the implementation of the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface that the slave will communicate with.  I.e. it is the master&amp;#039;s implementation of the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
The implementation of the &amp;lt;vp&amp;gt;slaveProcess&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement slaveProcess inherits slaveProcessSupport&lt;br /&gt;
    open pfc\&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new(Master) :-&lt;br /&gt;
        slaveProcessSupport::new(&amp;quot;slave.exe&amp;quot;),&lt;br /&gt;
        register_notify(&amp;quot;compilerMessage&amp;quot;, Master:compilerMessage).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compile(Filename, OnCompileResult) :-&lt;br /&gt;
        call_toRemote(predicate_name(), Filename, OnCompileResult).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    setSettings(Settings) :-&lt;br /&gt;
        notify_toRemote(predicate_name(), Settings).&lt;br /&gt;
&lt;br /&gt;
end implement slaveProcess&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The implementation inherits from &amp;lt;vp&amp;gt;slaveProcessSupport&amp;lt;/vp&amp;gt; which is initialized with a &amp;quot;path&amp;quot; to the slave program (which in our case is in the same directory as the master and has the name &amp;lt;vp&amp;gt;&amp;quot;slave.exe&amp;quot;&amp;lt;/vp&amp;gt;).  If needed we can also supply a command line for the program in this initialization call.&lt;br /&gt;
 &lt;br /&gt;
The implementation also registers all  calls and notifications of the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface. In this case it is just the &amp;lt;vp&amp;gt;compilerMessage&amp;lt;/vp&amp;gt; notification.&lt;br /&gt;
&lt;br /&gt;
Finally, the implementation contains a proxy method for each of the calls and notifications in the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
You will notice that registration as well as proxy methods is trivial code.&lt;br /&gt;
&lt;br /&gt;
=== masterProxy ===&lt;br /&gt;
&lt;br /&gt;
For the slave process we will need a proxy representing the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface provided by the master. The interface of this proxy looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
interface masterProxy supports master&lt;br /&gt;
&lt;br /&gt;
properties from pfc\masterSlaveProcessSupport&lt;br /&gt;
    fromLoop&lt;br /&gt;
&lt;br /&gt;
end interface masterProxy&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It simply supports the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; interface and provides a &amp;lt;vp&amp;gt;fromLoop&amp;lt;/vp&amp;gt; predicate that must be invoked to receive communication from the master.  We will return to this predicate below.&lt;br /&gt;
&lt;br /&gt;
The class declaration of the &amp;lt;vp&amp;gt;masterProxy&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class masterProxy : masterProxy&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (slave Slave).&lt;br /&gt;
&lt;br /&gt;
end class masterProxy&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The constructor takes the implementation of the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface as argument.  The implementation of the &amp;lt;vp&amp;gt;masterProxy&amp;lt;/vp&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement masterProxy inherits masterProxySupport&lt;br /&gt;
    open pfc\&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    new(Slave) :-&lt;br /&gt;
        register_call(&amp;quot;compile&amp;quot;, Slave:compile),&lt;br /&gt;
        register_notify(&amp;quot;setSettings&amp;quot;, Slave:setSettings).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compilerMessage(Message) :-&lt;br /&gt;
        notify_toRemote(predicate_name(), Message).&lt;br /&gt;
&lt;br /&gt;
end implement masterProxy&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It inherits from &amp;lt;vp&amp;gt;masterProxySupport&amp;lt;/vp&amp;gt; and contains registration of all &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; calls and notifications, and proxy implantations of all &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; calls and notifications.&lt;br /&gt;
&lt;br /&gt;
=== The master program ===&lt;br /&gt;
&lt;br /&gt;
The master program (i.e. the builder) is a console program that &lt;br /&gt;
* compiles a set of files&lt;br /&gt;
* using a number of slave-compilers and &lt;br /&gt;
* writes the messages from the compilers to the console.&lt;br /&gt;
Finally after all compilation is completed it will write some statistics to the console.&lt;br /&gt;
&lt;br /&gt;
This is done by the &amp;lt;vp&amp;gt;compiler::compileFiles&amp;lt;/vp&amp;gt; predicate&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class compiler : compiler&lt;br /&gt;
    open core&lt;br /&gt;
    [noDefaultConstructor]&lt;br /&gt;
&lt;br /&gt;
predicates&lt;br /&gt;
    compileFiles : (string Settings, setM{string} Files, positive ProcessCount) -&amp;gt; pfc\asynchronous\future{string} Result.&lt;br /&gt;
&lt;br /&gt;
end class compiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see the &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt; class can actually (privately) create objects of type &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt;. Each of these objects represents a compiler subprocess, but the management of these are kept privately in the implementation of the &amp;lt;vp&amp;gt;compiler&amp;lt;/vp&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
The compiler interface declares a &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; predicate and will not be shown here. Instead we will look at the implementation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement compiler&lt;br /&gt;
    supports master&lt;br /&gt;
    open compiler_ms\, slave, pfc\asynchronous\, continuationExtension&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles(Settings, Files, ProcessCount) = R :-&lt;br /&gt;
        CL = [ compileFiles2(Settings, Files) || _ = std::cIterate(ProcessCount) ],&lt;br /&gt;
        FC = future::fold(CL, compilerResult_zero, plus),&lt;br /&gt;
        R = FC:map(asString).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    compileFiles2 : (string Settings, setM{string} Files) -&amp;gt; future{compile_rsp}.&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles2(Settings, Files) =&lt;br /&gt;
        promise::newContinuation(&lt;br /&gt;
            { (Cont) :-&lt;br /&gt;
                Compiler = compiler::new(Settings),&lt;br /&gt;
                Compiler:doCompileFiles(Files, compilerResult_zero, Cont)&lt;br /&gt;
            }).&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    slave : slaveProcess.&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : (string Settings).&lt;br /&gt;
clauses&lt;br /&gt;
    new(Settings) :-&lt;br /&gt;
        slave := slaveProcess::new(This),&lt;br /&gt;
        slave:setNativeCreationFlags(multiThread_native::idle_priority_class),&lt;br /&gt;
        slave:run(),&lt;br /&gt;
        slave:setSettings(Settings).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    doCompileFiles(Files, Acc, OnCompileResult) :-&lt;br /&gt;
        if File = Files:tryRemoveFirst() then&lt;br /&gt;
            slave:compile(File,&lt;br /&gt;
                OnCompileResult:mkContinue(&lt;br /&gt;
                    { (CR) :-&lt;br /&gt;
                        stdio::writef(&amp;quot;    %s %s\n&amp;quot;, File, CR:asString()),&lt;br /&gt;
                        doCompileFiles(Files, Acc:plus(CR), OnCompileResult)&lt;br /&gt;
                    }))&lt;br /&gt;
        else&lt;br /&gt;
            slave:terminate_toRemote(),&lt;br /&gt;
            OnCompileResult:success(Acc)&lt;br /&gt;
        end if.&lt;br /&gt;
&lt;br /&gt;
constants&lt;br /&gt;
    compilerResult_zero : compile_rsp = compile_rsp(0, 0, 0).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    asString : (compile_rsp CompileResponse [this]) -&amp;gt; string.&lt;br /&gt;
clauses&lt;br /&gt;
    asString(compile_rsp(LineCount, Errors, CompilationTime)) =&lt;br /&gt;
        string::format(&amp;quot;% lines in %p % erros&amp;quot;, LineCount, duration::new(CompilationTime), Errors).&lt;br /&gt;
&lt;br /&gt;
class predicates&lt;br /&gt;
    plus : (compile_rsp A [this], compile_rsp B) -&amp;gt; compile_rsp C.&lt;br /&gt;
clauses&lt;br /&gt;
    plus(compile_rsp(AL, BL, CL), compile_rsp(AR, BR, CR)) = compile_rsp(AL + AR, BL + BR, CL + CR).&lt;br /&gt;
&lt;br /&gt;
% master&lt;br /&gt;
clauses&lt;br /&gt;
    compilerMessage(compilerMessage_ntf(File, Line, Message)) :-&lt;br /&gt;
        stdio::writef(&amp;quot;        %s(%d): %s\n&amp;quot;, File, Line, Message).&lt;br /&gt;
&lt;br /&gt;
end implement compiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The asynchronous method in the master/slave concept are based on &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;&amp;#039;s.  It is outside the scope of this article to go into details about asynchronous programming, &amp;lt;vp&amp;gt;promises&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;futures&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;&amp;#039;s.&lt;br /&gt;
&amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;&amp;#039;s are more lightweight and efficient than &amp;lt;vp&amp;gt;promises&amp;lt;/vp&amp;gt;/&amp;lt;vp&amp;gt;futures&amp;lt;/vp&amp;gt;, but also offer less functionality.  &lt;br /&gt;
Here we want the main thread to wait for the result of a number of compilers it has started, and for such combined waiting and result summing, we will use promises.  So the predicate &amp;lt;vp&amp;gt;compileFiles2&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
class predicates&lt;br /&gt;
    compileFiles2 : (string Settings, setM{string} Files) -&amp;gt; future{compile_rsp}.&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles2(Settings, Files) =&lt;br /&gt;
        promise::newContinuation(&lt;br /&gt;
            { (Cont) :-&lt;br /&gt;
                Compiler = compiler::new(Settings),&lt;br /&gt;
                Compiler:doCompileFiles(Files, compilerResult_zero, Cont)&lt;br /&gt;
            }).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starts a &amp;quot;compiler&amp;quot; and return the result as a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;.  &amp;lt;vp&amp;gt;promise::newContinuation&amp;lt;/vp&amp;gt; is a predicate that can &amp;quot;lift&amp;quot; a &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt; based routine into a &amp;lt;vp&amp;gt;future&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The main entry predicate &amp;lt;vp&amp;gt;compileFiles&amp;lt;/vp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    compileFiles(Settings, Files, ProcessCount) = R :-&lt;br /&gt;
        CL = [ compileFiles2(Settings, Files) || _ = std::cIterate(ProcessCount) ],&lt;br /&gt;
        FC = future::fold(CL, compilerResult_zero, plus),&lt;br /&gt;
        R = FC:map(asString).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starts &amp;lt;vp&amp;gt;ProcessCount&amp;lt;/vp&amp;gt; compilers and uses &amp;lt;vp&amp;gt;future::fold&amp;lt;/vp&amp;gt; and &amp;lt;vp&amp;gt;map&amp;lt;/vp&amp;gt; to wait for their termination and summing up the result.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; contains the heart loop of the compilation. Each started compiler will be controlled with a &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
clauses&lt;br /&gt;
    doCompileFiles(Files, Acc, OnCompileResult) :-&lt;br /&gt;
        if File = Files:tryRemoveFirst() then&lt;br /&gt;
            slave:compile(File,&lt;br /&gt;
                OnCompileResult:mkContinue(&lt;br /&gt;
                    { (CR) :-&lt;br /&gt;
                        stdio::writef(&amp;quot;    %s %s\n&amp;quot;, File, CR:asString()),&lt;br /&gt;
                        doCompileFiles(Files, Acc:plus(CR), OnCompileResult)&lt;br /&gt;
                    }))&lt;br /&gt;
        else&lt;br /&gt;
            slave:terminate_toRemote(),&lt;br /&gt;
            OnCompileResult:success(Acc)&lt;br /&gt;
        end if.&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 Basically the loop will try to obtain and remove &amp;lt;vp&amp;gt;File&amp;lt;/vp&amp;gt; to compile from the &amp;lt;vp&amp;gt;Files&amp;lt;/vp&amp;gt; to compile.  Since several loops will do this in parallel it is important that &amp;lt;vp&amp;gt;tryRemoveFirst&amp;lt;/vp&amp;gt; is thread safe.  In this example this is ensured by using a &amp;lt;vp&amp;gt;setM_redBlack_cas&amp;lt;/vp&amp;gt;  (i.e. a &amp;#039;&amp;#039;compare and swap&amp;#039;&amp;#039; red black set; see the &amp;lt;vp&amp;gt;main::run&amp;lt;/vp&amp;gt; implementation).&lt;br /&gt;
 &lt;br /&gt;
 If a &amp;lt;vp&amp;gt;File&amp;lt;/vp&amp;gt; can be removed from the set the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; is asked to &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; it (asynchronous using a &amp;lt;vp&amp;gt;continuation&amp;lt;/vp&amp;gt;).  When thew compilation is completed, we will write the result to stdio and loop to &amp;lt;vp&amp;gt;doCompileFiles&amp;lt;/vp&amp;gt; again.&lt;br /&gt;
 &lt;br /&gt;
 This will continue until &amp;lt;vp&amp;gt;Files&amp;lt;/vp&amp;gt; becomes empty in which case the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; is informed to terminate (&amp;lt;vp&amp;gt;slave:terminate_toRemote()&amp;lt;/vp&amp;gt;), and the accumulated result is returned.&lt;br /&gt;
 &lt;br /&gt;
 The &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; also supports the &amp;lt;vp&amp;gt;compilerMessage&amp;lt;/vp&amp;gt; notification:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
 clauses&lt;br /&gt;
    compilerMessage(compilerMessage_ntf(File, Line, Message)) :-&lt;br /&gt;
        stdio::writef(&amp;quot;        %s(%d): %s\n&amp;quot;, File, Line, Message).&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our case it simply writes the messages to the standard output stream.&lt;br /&gt;
 &lt;br /&gt;
=== The slave program ===&lt;br /&gt;
&lt;br /&gt;
The slave program is also a console program.  But it is very important to notice that the slave does not have a console window attached and that the console  input/output streams are used for communication with the master and can therefore &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; be used for other input/output.&lt;br /&gt;
&lt;br /&gt;
In this slave program everything interesting is packed into the implementation of &amp;lt;vp&amp;gt;theCompiler&amp;lt;/vp&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;&lt;br /&gt;
implement theCompiler&lt;br /&gt;
    supports slave&lt;br /&gt;
    open compiler_ms\, master, pfc\asynchronous\, continuationExtension&lt;br /&gt;
&lt;br /&gt;
facts&lt;br /&gt;
    master : masterProxy [constant].&lt;br /&gt;
    settings : string := &amp;quot;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    run() :-&lt;br /&gt;
        new():wait().&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    wait() :-&lt;br /&gt;
        _ = master:fromLoop:get().&lt;br /&gt;
&lt;br /&gt;
constructors&lt;br /&gt;
    new : ().&lt;br /&gt;
clauses&lt;br /&gt;
    new() :-&lt;br /&gt;
        master := masterProxy::new(This).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    compile(Filename, OnCompileResult) :-&lt;br /&gt;
        OnCompileResult:completeWith(&lt;br /&gt;
            {  = compile_rsp(Lines, Errors:value, D:get()) :-&lt;br /&gt;
                T1 = time::now(),&lt;br /&gt;
                Errors = varM_integer::new(),&lt;br /&gt;
                Lines = 20 + math::random(3000),&lt;br /&gt;
                foreach I = std::cIterate(Lines) + 1 and not(master:fromLoop:isCompleted()) do&lt;br /&gt;
                    foreach _ = std::cIterate(math::random(10000)) do&lt;br /&gt;
                    end foreach,&lt;br /&gt;
                    R = math::random(),&lt;br /&gt;
                    if R &amp;lt; 1 / 2000 then&lt;br /&gt;
                        Errors:inc(),&lt;br /&gt;
                        master:compilerMessage(compilerMessage_ntf(Filename, I, settings))&lt;br /&gt;
                    end if&lt;br /&gt;
                end foreach,&lt;br /&gt;
                D = duration::new(T1, time::now())&lt;br /&gt;
            }).&lt;br /&gt;
&lt;br /&gt;
clauses&lt;br /&gt;
    setSettings(Settings) :-&lt;br /&gt;
        settings := Settings.&lt;br /&gt;
&lt;br /&gt;
end implement theCompiler&lt;br /&gt;
&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vp&amp;gt;theCompiler&amp;lt;/vp&amp;gt; implements the &amp;lt;vp&amp;gt;slave&amp;lt;/vp&amp;gt; interface which it pass as argument to the constructor of the &amp;lt;vp&amp;gt;masterProxy&amp;lt;/vp&amp;gt; object, thereby the communication and message loops are established.&lt;br /&gt;
&lt;br /&gt;
In this program the main thread will simply wait for the termination of the &amp;lt;vp&amp;gt;fromLoop&amp;lt;/vp&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The master can notify the slave about settings using &amp;lt;vp&amp;gt;setSettings&amp;lt;/vp&amp;gt; notification.  You should be aware that the entries in a slave are unsynchronized and can be invoked in parallel by the master.  The master can make calls sequential by making next call when the current completes, but the master has no means of knowing when a notification has been &amp;quot;completed&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;vp&amp;gt;compile&amp;lt;/vp&amp;gt; call completes the OnCompileResult continuation with the result of a little function that simulates a compilation.  The simulation &amp;quot;compiles&amp;quot; a random number of lines each with a certain probability to issue a compilerMessage which is notified back to the &amp;lt;vp&amp;gt;master&amp;lt;/vp&amp;gt; (i.e. through the proxy object).&lt;br /&gt;
&lt;br /&gt;
The compilation also test for termination request from the master (i.e. &amp;lt;vp&amp;gt;master:fromLoop:isCompleted()&amp;lt;/vp&amp;gt;), this test would actually only be relevant if the compilation was terminated in the middle of compilation which this example will never do.  But when compiling files from an IDE it is custom to have a &amp;quot;stop compilation&amp;quot; facility.  This facility could wait all compilers to ask for the next file to compile and terminate them there, but it could also send a terminate request to the slave, in which case the fromLoop would complete.&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Thomas Linder Puls</name></author>
	</entry>
</feed>