<?xml version="1.0" encoding="iso-8859-1"?>

<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:cc="http://web.resource.org/cc/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns="http://purl.org/rss/1.0/">

<channel rdf:about="http://www.lenholgate.com/">
<title>/* Rambling comments... */</title>
<link>http://www.lenholgate.com/</link>
<description>Len Holgate&apos;s thoughts on this and that...
Mainly test driven software development in C++ on Windows platforms...</description>
<dc:language>en-us</dc:language>
<dc:creator></dc:creator>
<dc:date>2010-08-15T11:06:21+00:00</dc:date>
<admin:generatorAgent rdf:resource="http://www.movabletype.org/?v=2.64" />


<items>
<rdf:Seq><rdf:li rdf:resource="http://www.lenholgate.com/archives/000925.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000924.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000923.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000922.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000921.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000920.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000919.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000918.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000917.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000916.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000915.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000914.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000913.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000912.html" />
<rdf:li rdf:resource="http://www.lenholgate.com/archives/000911.html" />
</rdf:Seq>
</items>

</channel>

<item rdf:about="http://www.lenholgate.com/archives/000925.html">
<title>DevPartner Studio 10 - unmanaged disappointments</title>
<link>http://www.lenholgate.com/archives/000925.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000925.html">11:06 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=925" >Comments (2)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_rants.html">Rants</a>

	</div>]]>

<![CDATA[<p>The story so far, I've owned DevPartner Studio for several years and been on a support contract the whole time. The support situation went a bit flakey when Compuware sold the product to Micro Focus, I expect that either I'm simply not a big enough client for them to care or their post sales and support is just no where near as good as the Compuware offering. With Compuware I'd be contacted when new versions came out and I had a named sales contact that I could also use for questions, etc. What's more the sales guy was good, he knew I wouldn't be buying more licenses, he remembered the issues I'd raised and he helped chase up responses etc. </p>

<p>Anyway, <a href="http://www.lenholgate.com/archives/000914.html">I whinged</a> about how DevPartner lagged behind Visual Studio releases and was told, via a comment from someone at Micro Focus, that DevPartner 10 shipped at the same time as Visual Studio 2010; it would have been nice if my support contract meant that they'd bother to tell me about this since I was entitled to the latest version; heh, here's an idea, the software itself could work it out for me somehow (nah, nobody would do that)... Anyway, it seems that the way I'm supposed to work out that a new version that I'm entitled to under my support contract is available is to log on to the Micro Focus support site and 'request a new version'.  Presumably I either poll this site every couple of months and request current version + 1 or I'm supposed to track when they release new versions... Interestingly I get a list of patches for 9.1 displayed but no indication that a 10 is available... </p>

<p>So, I fill in the form and wait a few days, no response, I chase them and eventually get an email with some download links. I download and install DevPartner 10 and run it up in "Error detection" mode on an unmanaged VS2010 solution which contains a <a href="http://www.lenholgate.com/archives/000921.html">relatively simple multi-threaded project</a>... </p>

<p>During the build I get several compiler crashes and whilst it IS the Microsoft C++ compiler that is crashing here it has never crashed with this code if DevPartner instrumentation is NOT enabled... The errors are all similar:<br />
<pre>1>e:\source\practicaltesting\jetbytetools\testtools\testmonitor.cpp(748): fatal error C1001: An internal error has occurred in the compiler.<br />
1>  (compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c[0x524EDFBA:0x00000004]', line 183)<br />
1>   To work around this problem, try simplifying or changing the program near the locations listed above.<br />
1>  Please choose the Technical Support command on the Visual C++ <br />
1>   Help menu, or open the Technical Support help file for more information</pre><br />
And they all occur in these kinds of situations...<br />
<pre>   }<br />
   catch(const CSEHException &e)<br />
   {<br />
      cout << "Exception during test timeout processing: " << CStringConverter::TtoA(e.GetWhere() + _T(" - ") + e.GetMessage()) << endl;<br />
   }<br />
   JETBYTE_TESTS_CATCH_ALL_AT_THREAD_BOUNDARY_IF_ENABLED<br />
   {<br />
      cout << "Unecpedted exception during test timeout processing" << endl;<br />
   }</pre><br />
Where the macro evaluates to <code>catch(...)</code> in this particular build.</p>

<p>So, my first impression of the new version is that it's just about as good as the first impression I had of 9.0, i.e. it simply doesn't work on the latest compiler with simple code. I don't know if I'm alone in thinking that when software that you're supposed to rely on for software quality assurance work gives this kind of first impression you tend to worry if it actually does what it needs to at all, rather than simply being a rushed to market mess which underwent too little testing before release so that it could be shipped at the same time as the new compiler without actually supporting it...</p>

<p>Anyway, I thought, perhaps, that by default there were too many error detection options turned on (I tend to use a small subset of the functionality as I've found that the more interesting stuff is prone to not work (API parameter checking is great until you realise that some of the (admittedly many) APIs that it covers are configured incorrectly and report problems that don't exist and you can't change them and have to wait for a service release...). Anyway, off I go to the options screen and find that I can't change the error detection options as "Error Detection settings are unavailable until you select  a valid start up project"...</p>

<p>At this point I switched to VS2008 to see how things were back in the legacy compiler environment. This time everything builds OK but when I go to run the program under BoundsChecker I get a message telling me that DevPartner is unable to test 64bit projects. Fair enough; we're still in 'tool lag' country, DevPartner 9.1 could also only 'run on' x64 and not instrument x64 code; then the tool would also try and instrument the x64 builds but the link failure messages were fairly clear in what was wrong. It's a pity that the DevPartner 10 user interface isn't consistent on this, the VS2010 options screen obviously knows it's not supposed to let you work with x64 projects (though could be more helpful) yet the tool bars and build process let you try to build x64 projects rather than, more helpfully, preventing you...</p>

<p>Rebuilding the 32bit version of the code in VS2010 worked OK, but what a wonderful first impression...</p>

<p>Now there seem to be some new weird problem reports inside of the VS2010 STL code which I need to dig my way through to determine why they're OK to ignore... </p>

<p>And then I suppose I need to go and dig up all of the same information that they already have about my development machine so that I can ask them to send me a new license file...</p>]]>


<![CDATA[<p><map name="google_ad_map_100815110621">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100815110621?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100815110621" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100815110621&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000925.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000925.html">11:06 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=925" >Comments (2)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_rants.html">Rants</a>

	</div>]]>



</description>


<dc:subject>Rants</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-15T11:06:21+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000924.html">
<title>More thoughts on invasive/intrusive containers and STL allocators</title>
<link>http://www.lenholgate.com/archives/000924.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000924.html">04:09 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=924" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>

<![CDATA[<p>I'm still considering my options with regards to intrusive containers to replace the STL maps that I'm using in my timer queue implementation. I think I may be able to use the <code>boost::intrusive</code> sets in place of a true map in most of the situations that I need (I just have convince myself that a) it will work with all the compilers that I need to support, b) that  adding a dependency to part of boost is a good idea for me and my clients and c) that even though my gut reaction on seeing the code is that it's pointlessly clever and bound to be a bitch to debug it's probably better than rolling my own). </p>

<p>I can't help but think that this whole issue would have never existed if the standard STL allocators had taken the value type as an argument to <code>allocate()</code>, this is likely not possible with things other than <code>std::set</code> and <code>std::map</code> BUT if these took the value type as a parameter then a custom allocator could simply locate the intrusive link structure in the value type and return that to the container. The same underlying map template could then work with either an allocator that allocates its node structure or an allocator that obtains the intrusive structure from the value type... Since it would have been this simple we'd have had the option of intrusive STL containers from day 0...</p>

<p>It's very tempting to hack this kind of change into a copy of the map/set/tree templates used in STLPort rather than writing my own...</p>]]>


<![CDATA[<p><map name="google_ad_map_100805160954">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100805160954?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100805160954" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100805160954&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000924.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000924.html">04:09 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=924" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>



</description>


<dc:subject>Geek Speak</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-05T16:09:54+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000923.html">
<title>CLR Hosting - A flexible, managed plugin system, part 2</title>
<link>http://www.lenholgate.com/archives/000923.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000923.html">10:36 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=923" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_clr_hosting.html">CLR Hosting</a>
, <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>

<![CDATA[<p><a href="http://www.lenholgate.com/archives/000916.html">Last time</a> I explained how the managed side of my flexible hosting server architecture was structured. I dealt with the IDL required to generate the COM interfaces which were used to communicate between unmanaged code and managed code and detailed how the custom <code>AppDomainManager</code> object allowed me to load and execute managed code in such a way that it was easy to update the managed applications whilst the server was running.</p>

<p>This time I'll cover the unmanaged side of things. This is actually where much of the complexity lives. The code that actually manages the creation and destruction of the application domains in which the managed applications run and which deals with wiring them up to the network endpoints that are accepting connections for them.</p>]]>
<![CDATA[<p>The unmanaged code has an object which represents the collection of applications that it runs. This <code>CApplicationCollection</code> class contains the CLR hosting code, <code>CManagedHost</code>, a collection of application details for each application that it is configured to run and an additional collection of running applications. Thus the application details collection represents all of the applications than CAN run and the application collection represents all of the applications that ARE running.</p>

<p>This allows me to load a set of applications that can be run when the server starts up and start them. I can then tell each network endpoint the name of the application that connections are to be routed to and as each new connection comes in the socket server that is managing that end point can look up the application by name in the <code>CApplicationCollection</code> and connect the connection to it. If the application is not running then the connection will fail and be closed after issuing an error message.</p>

<p>Since there's a difference between applications that the server CAN run and applications that ARE running I can easily restart an application by locating the running instance, telling it we're about to shut down and then unloading its application domain. Meanwhile I can create a new application domain, start a new copy of the managed application, based on the application details that are stored for the application, and insert it into the running applications collection. In fact I do this in reverse, starting and inserting the new application and then shutting down the old. This minimises the time when an application isn't available.</p>

<p>Whenever an application is stopped I need to be able to walk the list of connections that are currently connected to the application and terminate them. This requires that the unmanaged application objects maintain a collection of active connections. This deals with the 'kill' style restarts that I spoke of in the <a href="http://www.lenholgate.com/archives/000916.html">previous article</a>. To handle the 'kind' restarts I need to be able to keep a running application around after it has been removed from the running applications collection and only unload its application domain when all currently active connections have been completed. To enable this the application object is reference counted and the application domain is unloaded when the application object is deleted. This allows me to have each active connection hold a reference to the application that it is connected to and also have the <code>CApplicationCollection</code> hold a reference whilst it has the application in its collection of running applications. When the application is restarted it is removed from the running applications collection and the reference owned by the <code>CApplicationCollection</code> is released, now only the active connections are keeping the application alive and when the last of those ends the application domain is unloaded. Meanwhile we've already started a new copy of the application and placed it in the running applications collection and so new connections go to the new copy of the application and existing connections continue in the old copy.</p>

<p><img alt="ManagedApplicationCollection.png" src="http://www.lenholgate.com/archives/images/ManagedApplicationCollection.png" width="546" height="527" border="0" /></p>

<p>Automatic restarts are supported by enabling shadow copying on the application domains so that the assemblies aren't locked whilst the application is running and adding a directory change monitor to look for updated files. The directory change monitor starts a 10 second timer when it spots a file change and when the timer expires the application is restarted. The server demonstrates both kind and kill automatic restarts. The timer is necessary to prevent multiple restarts when files are updated by hand, ideally you set a timer for long enough to allow someone to copy or edit files and when the "quiet period" has expired the application is restarted. </p>

<p>Finally a management socket server presents a simple text based protocol that's accessible via telnet which allows the user to list and manipulate the applications. Right now you can't add new applications and endpoints to a running server but there's nothing in the architecture to prevent it. Likewise you can't remove endpoints but it could be added.</p>

<p>This code is all included in a <a href="http://www.lenholgate.com/ServerFramework/6.2/Docs/socketsamples.html">new example server</a> for The Server Framework which will ship with version 6.3.<br />
</p>]]>

<![CDATA[<p><map name="google_ad_map_100805103650">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100805103650?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100805103650" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100805103650&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000923.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000923.html">10:36 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=923" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_clr_hosting.html">CLR Hosting</a>
, <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>



</description>


<dc:subject>Socket Servers</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-05T10:36:50+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000922.html">
<title>Useful Visual Studio retirement matrix</title>
<link>http://www.lenholgate.com/archives/000922.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000922.html">08:26 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=922" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>

<![CDATA[<p>Here's a <a href="http://support.microsoft.com/lifecycle/search/?sort=PN&alpha=Visual+Studio">useful matrix</a> which shows when each version of Visual Studio will become unsupported by Microsoft. I'm posting the link here as I'm sure I'll not be able to find it the next time I need it...</p>]]>


<![CDATA[<p><map name="google_ad_map_100805082653">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100805082653?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100805082653" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100805082653&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000922.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000922.html">08:26 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=922" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>



</description>


<dc:subject>Geek Speak</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-05T08:26:53+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000921.html">
<title>Practical Testing: 28 - Finishing the timer wheel</title>
<link>http://www.lenholgate.com/archives/000921.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000921.html">12:54 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=921" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>

<![CDATA[<p>Previously on <a href="http://www.lenholgate.com/archives/000306.html">"Practical Testing"</a>...  I'm writing a <a href="http://www.lenholgate.com/archives/000909.html">timer wheel</a> which matches the interface used by my timer queue. This  new implementation is designed for a particular usage scenario with the intention of trading space for speed and improving performance of some reliable UDP code.</p>

<p>Over the last four entries I've implemented various parts of the timer wheel and adjusted the test code so that I could reuse the tests that I already had for the other implementations with my timer wheel. The tests needed to be tweaked quite a bit to take into account the different behavioural characteristics of the wheel and the queues, this was accomplished using traits which determine the detail of how the class under test interacts with its service providers (mainly a tick count provider).</p>

<p>Today we finally get to the point where we have a working timer wheel that is compatible with the interface used by the two timer queues. We can then look at the results of the performance tests and work out where we need to go next.  </p>]]>
<![CDATA[<p>The wheel that was presented in the <a href="http://www.lenholgate.com/archives/000918.html">previous entry</a> is mostly complete. In fact only three functions are left to implement and these three functions implement a single feature; the handling of timeouts without needing to hold a lock on the wheel during timeout dispatch, this functionality makes it impossible to deadlock due to lock inversions which involve the timer wheel. I described the changes that were required when I added this functionality to the timer queue <a href="http://www.lenholgate.com/archives/000795.html">here</a>, the changes required for the timer wheel are similar.</p>

<p>The main change is in how we store the timer data so that we can be dispatching an expired timer and setting, cancelling or destroying the same timer during the dispatch. We need to allow for this because the lock that should be held whilst you're updating the timer wheel is not held during timer dispatch. So, rather than holding a single set of timer data within the timer we hold two sets, an active set and a timed out set. When the timeout handling begins the call to <code>BeginTimeoutHandling()</code>, which should be protected by a lock, updates each of the timers to prepare it for timeout dispatch. This means that it needs to walk the list of timers for this time and copy the active set of data to the timed out set and clear the active set. Now when the timer is processed by <code>HandleTimeout()</code> we're working with the timed out set of data which allows the timer to be manipulated normally using the active data. Having to prepare the timers is a bit of a pain, it means that timer dispatch is <b>O(n)</b> where <b>n</b> is the number of timers to be dispatched, however this is the same as for the timer queue and we're avoiding the <b>O(log n)</b> (n being the number of timers currently set in this case) of the balanced tree lookup required for the timer queues...</p>

<p>There's still scope for some refactoring in the code and there's a need for some more tests to make sure that we're doing things sensibly when we fail to handle timeouts for a long period of time but this can be done later. I've added a few new tests to test the timer wheel with the <code>CThreadedCallbackTimerQueue</code>, I expect that could do with a name change now, but that can also wait.</p>

<p>Since we now have a fully functional timer wheel I can compare the performance results with those from the timer queue implementations. Note that these are the results that I get on my development box, the results that you get are likely to be different but the proportional differences should be similar... All test results are an average of 10 runs of the same test with 100,000 timers in use in each test.</p>

<ul>
<li><b>Creating timers</b> - Unsurprisingly, since very similar work is being done by both the queues and the wheel, <code>CreateTimer()</code> is roughly similar with the wheel actually taking fractionally longer at 55ms vs the queues which both take 50ms.</li>
<li><b>Setting timers</b> - Again unsurprisingly, the timer wheel is much faster when setting timers at 8ms compared to 88ms for the queue.  Note that the 8ms value is a best case scenario where we set and reset the same timer, with different timers the times rise to 15ms vs 130ms and with different timers being set for the same times we get 14ms vs 60ms. What doesn't show here is that the wheel is also only <b>C(n wheel users)</b> compared to the queue's <b>C(n wheel users)+2C(n heap users)</b> (see <a href="http://www.lenholgate.com/archives/000908.html">here</a> for details of my 'big C' notation for talking about contention).</li>
<li><b>HandleTimeouts</b> - When handling timeouts and holding the lock we get results of 54ms against 94ms for the queues. When not holding the locks the numbers are 57ms and 98ms. Again the wheel has lower contention.</li>
</ul>

<p>All in all I'm pleased with the performance and contention improvements that have come from using a radically different design. The timer wheel isn't as general purpose as the timer queues and it's not going to be a good fit for all of the usage scenarios that I use the queue in but for those situations that it <i>is</i> appropriate for, the performance will be considerably better.</p>

<p>The code can be found <a href="http://lenholgate.com/archives/zips/PracticalTesting-28.zip">here</a> and the <a href="http://www.lenholgate.com/archives/000906.html">previous rules</a> apply.</p>]]>

<![CDATA[<p><map name="google_ad_map_100804125416">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100804125416?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100804125416" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100804125416&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000921.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000921.html">12:54 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=921" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>



</description>


<dc:subject>Testing</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-04T12:54:16+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000920.html">
<title>Invasive containers</title>
<link>http://www.lenholgate.com/archives/000920.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000920.html">09:28 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=920" >Comments (1)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_c_tips.html">C++ Tips</a>
, <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>

<![CDATA[<p>Rather than immediately dive into the fun of writing my own <a href="http://www.lenholgate.com/archives/000907.html">invasive alternative</a> for <code>std::map</code> I decided to take a look at what has been done before, as expected <a href="http://www.boost.org/">boost</a> contains something that might work in the shape of the "<a href="http://www.boost.org/doc/libs/1_43_0/doc/html/intrusive.html">intrusive containers library</a>". </p>

<p>Of course, being part of boost I first have to work out exactly how much more of boost it will require me to depend on and then I have to work out how I can use it to replace my current <code>std::map</code> usage. It seems quite clever (no surprise there) and allows for a type to be included in multiple intrusive containers by allowing an object to have multiple links embedded in it and allowing you to specify the link to use for a particular container. It seems slightly over engineered for my needs (again, no surprise there) and it's a pity that it doesn't simply provide obvious drop in replacements for the equivalent STL containers; yes it's nice that there are two kinds of base tree structure (red black and AVL) so you can optimise for your specific usage patterns but it would be nicer if you could simply switch from <code>std::map</code> to <code>boost::intrusive::map</code> and add an appropriate data member to the class you want to store in it... </p>

<p>Still, I guess I should spend some more time learning and understanding... One thing that it doesn't do for me, as far as I can see, is provide a multimap from which I can remove all elements at a specific key in one go...</p>]]>


<![CDATA[<p><map name="google_ad_map_100804092808">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100804092808?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100804092808" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100804092808&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000920.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000920.html">09:28 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=920" >Comments (1)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_c_tips.html">C++ Tips</a>
, <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>



</description>


<dc:subject>Geek Speak</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-04T09:28:08+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000919.html">
<title>STL allocators, hmm...</title>
<link>http://www.lenholgate.com/archives/000919.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000919.html">07:17 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=919" >Comments (3)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_c_tips.html">C++ Tips</a>
, <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>

<![CDATA[<p>As I mentioned <a href="http://www.lenholgate.com/archives/000907.html">a while ago</a>, I have some code which needs to perform better than it currently does and one of the areas that could be improved upon is the amount of contention for the heap that's occurring. The fact that I'm using an STL <code>map</code> for my collection means that the class has a <a href="http://www.lenholgate.com/archives/000908.html">'big C'</a> contention value of <b>C(n threads using the heap)</b> rather than <b>C(n threads using the object)</b>. Of course, the fact that allocations need to be done at all is an unfortunate feature of <code>std::map</code> but rather than immediately replace the container with an invasive collection I decided to look into replacing the STL allocator that's being used with one that uses a private heap so  that I could reduce the contention value of the allocations to <b>C(n threads using the object)</b>. Doing this has required that I take a look at STL allocators and my initial thought is "hmm..."<br />
</p>]]>
<![CDATA[<p>STL containers can be configured to use custom allocators but by default they use a default allocator which, generally, uses the heap to allocate and free memory in a thread safe way. An allocator is a template parameter to the container and, as pointed out in several references, you don't generally need to mess with them. Still, my requirements are to improve performance and part of that job is to reduce potential contention so the allocators need to be looked at. <iframe align="right" src="http://rcm-uk.amazon.co.uk/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=ramcom-21&o=2&p=8&l=as1&m=amazon&f=ifr&md=0M5A6TN3AXP2JHJBWT02&asins=0201309564" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><br />
My reference books didn't adequately cover allocators, though <a href="http://www.amazon.co.uk/gp/product/0201309564?ie=UTF8&tag=ramcom-21&linkCode=as2&camp=1634&creative=19450&creativeASIN=0201309564">Generic Programming and the STL</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=ramcom-21&l=as2&o=2&a=0201309564" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> did explain it all in a rather terse manner with lots of "you don't need to know this" provisos.<br />
 <br />
A quick Google led me to <a href="http://www.tantalon.com/pete.htm">Pete Isensee's</a> pages where he talks about STL allocators for games programming. He has a nice set of slides and some code and this has helped me get started. </p>

<p>I can't help thinking that allocators weren't really thought through especially well; the whole 'rebind' from <code>allocator&lt;int&gt;</code> to <code>allocator&lt;node&gt;</code> is, IMHO, just pointless 'aren't we clever with templates' crap ;) especially given the fact that at the end of the day all these things are doing is allocating memory of a given size... </p>

<p>Anyway, being able to plug my own allocator into the containers is one small step on the path to improving the performance of the objects in question.</p>]]>

<![CDATA[<p><map name="google_ad_map_100804071715">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100804071715?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100804071715" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100804071715&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000919.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000919.html">07:17 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=919" >Comments (3)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_c_tips.html">C++ Tips</a>
, <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>

	</div>]]>



</description>


<dc:subject>Geek Speak</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-04T07:17:15+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000918.html">
<title>Practical Testing: 27 - Fixing things...</title>
<link>http://www.lenholgate.com/archives/000918.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000918.html">05:53 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=918" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>

<![CDATA[<p>Previously on <a href="http://www.lenholgate.com/archives/000306.html">"Practical Testing"</a>... To deal with some specific usage scenarios of a piece of general purpose code I'm in the process of implementing a <a href="http://www.lenholgate.com/archives/000909.html">timer wheel</a> that matches the interface to the timer queue that I previously developed in this <a href="http://www.lenholgate.com/archives/000306.html">series of articles</a>. Last time I left myself with a failing test. The problem is that setting a new timer on the timer wheel sets a timer that's relative to the time that timer wheel thinks is 'now' and the timer wheel's view of the current time could be slightly behind reality; see the <a href="http://www.lenholgate.com/archives/000913.html">previous entry</a> for a diagram that explains the problem.</p>]]>
<![CDATA[<p>This kind of problem wouldn't exist if the timer wheel was operating on a hard real time system where each tick of the hardware clock caused the timer wheel to 'rotate' and process timers that have expired. Unfortunately since we just have a normal thread to process timers the wheel can get slightly behind reality. There are two ways to solve this problem and both have drawbacks. The first is to cause the wheel to be processed before any new timer is set, this would mean that the wheel is always up to date and therefore the timer insertion would be correct. Unfortunately this leads to timers being handled on any thread that calls <code>SetTimer()</code> which may not be ideal for users of the wheel, it also means that setting a timer is no longer O(1)... The second approach is to simply set the timer based on the current time and allow for the difference between the current time and the timer wheel's view of the current time when the timer is inserted into the wheel. The disadvantage with this approach is that the maximum timeout that can be set will fluctuate around the lag between 'now' and the timer wheel's view of 'now'. You can work around this fluctuation by making the wheel have a maximum timeout that is larger than the actual maximum timeout that you wish to set and the expected lag...</p>

<p>I've taken the second approach as non O(1) timer setting and 'random thread timer dispatch' are not desirable qualities for the usage scenarios that I'm currently targeting. This means that the timer wheel now queries the tick count provider when you call <code>SetTimer()</code> but it's easy to adjust the tests for this due to the test traits that I introduced a while back.</p>

<p>Now that <code>SetTimer()</code> works correctly we can move on to implementing the remaining functions. Unfortunately though, before we do that we need to deal with a memory leak bug in the <code>CCallbackTimerQueueBase</code> class which the tests can't detect and which I missed due to <a href="http://www.lenholgate.com/archives/000914.html">not running BoundsChecker</a> after each set of changes... The leak was introduced when I switched from using the <code>std::multimap</code> to using a <code>std::deque</code> back in <a href="http://www.lenholgate.com/archives/000907.html">part 21</a>. Unfortunately I missed out a couple of <code>delete</code> statements to clear up the new structure that we allocate to store in the <code>std::deque</code>  when we set timers. This just goes to show that it doesn't matter how many tests you have and how good your coverage is, it's never enough to prove that the code is without bugs. Running BoundsChecker showed the bug quite clearly but it's a pity that it needs to be a separate stage of testing. Instrumenting memory allocation within the test would help and is something that I might look into... Anyway, the fixes are to add a loop which cleans up the allocated memory in the queue's destructor and to clean up blocks of timers as they expire in <code>HandleTimeouts()</code>.</p>

<p>The code can be found <a href="http://lenholgate.com/archives/zips/PracticalTesting-27.zip">here</a> and the <a href="http://www.lenholgate.com/archives/000906.html">previous rules</a> apply.</p>]]>

<![CDATA[<p><map name="google_ad_map_100803175350">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100803175350?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100803175350" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100803175350&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000918.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000918.html">05:53 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=918" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>



</description>


<dc:subject>Testing</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-03T17:53:50+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000917.html">
<title>.Net 4.0 different AppDomain managers for different AppDomains</title>
<link>http://www.lenholgate.com/archives/000917.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000917.html">10:47 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=917" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_clr_hosting.html">CLR Hosting</a>

	</div>]]>

<![CDATA[<p>Whilst looking through the latest documentation for the <code><a href="http://msdn.microsoft.com/en-us/library/system.appdomainsetup_members.aspx">AppDomainSetup</a></code> class I see that you can now specify a new <code>AppDomainManager</code> object for each application domain that you create. This removes the duality of the pre 4.0 <code>AppDomainManager</code> as the manager that you specify when you start the CLR can now deal solely with the requirements of the default application domain and it can set a new <code>AppDomainManager</code> object for each application domain that it creates. </p>]]>


<![CDATA[<p><map name="google_ad_map_100803104741">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100803104741?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100803104741" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100803104741&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000917.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000917.html">10:47 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=917" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_clr_hosting.html">CLR Hosting</a>

	</div>]]>



</description>


<dc:subject>CLR Hosting</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-08-03T10:47:41+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000916.html">
<title>CLR Hosting - A flexible, managed plugin system, part 1</title>
<link>http://www.lenholgate.com/archives/000916.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000916.html">06:27 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=916" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_clr_hosting.html">CLR Hosting</a>
, <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>

<![CDATA[<p>I'm working on some prototype code right now to improve the "deployment characteristics" of a socket server that I wrote for a client which uses CLR hosting to provide multiple managed applications within a single unmanaged host. The client wants to be able to start, stop and restart individual managed applications within the server so that during development or when a managed application is updated they don't need to restart the whole unmanaged server process to use a new version of a managed application. This is all quite easy to do using separate application domains for each managed "application" within the unmanaged host but, as always, the devil is in the detail. Their existing server is already using an application domain per application but no thought was given to being able to dynamically unload and reload applications whilst the unmanaged host was running. </p>

<p>I've got to the point where I have a nice new server framework <a href="http://www.lenholgate.com/ServerFramework/6.2/Docs/socketsamples.html">example server</a> that demonstrates all of the functionality I need and so it feels like the right time to write about how I got here.</p>]]>
<![CDATA[<p><iframe  align="right" src="http://rcm-uk.amazon.co.uk/e/cm?t=ramcom-21&o=2&p=8&l=as1&asins=0735619883&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>Hosting the CLR is fairly straight forward and, from an unmanaged point of view, it's all just COM, so it's nice and familiar. First you obtain an instance of <code><a href="http://msdn.microsoft.com/en-us/library/ms164408.aspx">ICLRRuntimeHost</a></code> using whichever API is most appropriate for you, either <code><a href="http://msdn.microsoft.com/en-us/library/99sz37yh.aspx">CorBindToRuntimeEx()</a></code> or <code><a href="http://msdn.microsoft.com/en-us/library/dd537633.aspx">CLRCreateInstance()</a></code>, <code><a href="http://msdn.microsoft.com/en-us/library/dd233134.aspx">ICLRMetaHost</a></code> and <code><a href="http://msdn.microsoft.com/en-us/library/dd233121.aspx">ICLRRuntimeInfo</a></code>. Once you have your runtime host you can connect it to your unmanaged host by calling <code><a href="http://msdn.microsoft.com/en-us/library/ms164414.aspx">ICLRRuntimeHost::SetHostControl()</a></code>. With that done you provide an implementation of an <code><a href="http://msdn.microsoft.com/en-us/library/system.appdomainmanager.aspx">AppDomainManager</a></code>, tell the CLR the assembly and type to use and start the CLR. All of this is covered in <a href="http://www.amazon.co.uk/gp/product/0735619883?ie=UTF8&tag=ramcom-21&linkCode=as2&camp=1634&creative=6738&creativeASIN=0735619883">Customizing the Microsoft.NET Framework Common Language Runtime</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=ramcom-21&l=as2&o=2&a=0735619883" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, which is well worth getting if you want to do this kind of thing.</p>

<p>The only thing that you really need to do in your custom <code>AppDomainManager</code> registered is make sure that you implement <code>InitializeNewDomain()</code> so that you set the flags to tell the CLR to register new application domains with your unmanaged host.  <br />
<pre>      public override void InitializeNewDomain(AppDomainSetup appDomainInfo)<br />
      {<br />
         // let the unmanaged host know about us<br />
         InitializationFlags = AppDomainManagerInitializationOptions.RegisterWithHost;<br />
      }</pre><br />
With that set you'll get a call into your <code><a href="http://msdn.microsoft.com/en-us/library/ms164473.aspx">IHostControl::SetAppDomainManager()</a></code> method for each application domain that's created. To be able to do anything interesting with your hosting powers you probably want to create an interface for communicating between your unmanaged host and your managed <code>AppDomainManager</code>, and possibly one for communicating back the other way. I find it easiest to create the interfaces in the old school COM way in an IDL file that is compiled into a type library and then imported into an assembly. For me this gives me all that I want without any of the cruftiness of the other ways of doing this. The IDL from my example server for its <code>AppDomainManager</code> looks like this.<br />
<pre>   [<br />
      object,<br />
      uuid(0EC4D543-008A-4cd3-88DB-A5199F416251),<br />
      helpstring("IManagedHost Interface"),<br />
      pointer_default(unique)<br />
   ]<br />
   interface IManagedHost : IUnknown<br />
   {<br />
      HRESULT InitialiseDefaultAppDomain(<br />
         [in] IUnmanagedHost *host);<br />
  <br />
      HRESULT CreateApplicationInNewAppDomain(<br />
         [in] BSTR appDomainName,<br />
         [in] BSTR applicationName,<br />
         [in] BSTR applicationDirectory,<br />
         [in] BSTR sharedDirectory,<br />
         [in] BSTR configFileName,<br />
         [in] BOOL enableShadowCopy,<br />
         [out, retval] long *pDomainID);<br />
  <br />
      HRESULT Start(<br />
         [in] BSTR assemblyName,<br />
         [in] BSTR typeName,<br />
         [in] BSTR applicationName,<br />
         [out, retval] IManagedApplication **application);<br />
  <br />
      HRESULT RequestStop();<br />
  <br />
      HRESULT Stop();<br />
   };</pre>  <br />
I then implement this in my managed <code>AppDomainManager</code> and QI for it when <code>IHostControl::SetAppDomainManager()</code> is called.<br />
<pre>HRESULT CManagedHost::SetAppDomainManager(<br />
  DWORD dwAppDomainID,<br />
  IUnknown *pUnkAppDomainManager)<br />
{<br />
   ICriticalSection::Owner lock(m_criticalSection);<br />
  <br />
   DomainManagerMap::iterator it = m_domainManagers.find(dwAppDomainID);<br />
  <br />
   if (m_domainManagers.end() != it)<br />
   {<br />
      it->second = SafeRelease(it->second);<br />
   }<br />
  <br />
   IManagedHost *pHost = 0;<br />
  <br />
   const HRESULT hr = pUnkAppDomainManager->QueryInterface(IID_IManagedHost, (void**)&pHost);<br />
  <br />
   if (SUCCEEDED(hr))<br />
   {<br />
      m_domainManagers[dwAppDomainID] = pHost;<br />
   }<br />
  <br />
   return hr;<br />
}</pre><br />
When writing a system to load and unload plugins (or applications) you need to be aware that you can't unload the "default application domain". In effect there's the "default application domain" and all the other application domains (secondary application domains). Plugin code should be loaded into a new application domain so that it's isolated and so that it can be unloaded without needing to restart the hosting process. Since you can only have one type as an <code>AddDomainManager</code> for all application domains this can cause the custom <code>AppDomainManager</code> to have two distinct roles. The first is to be the manager of the default application domain. In this role it's responsible for creating new application domains. The second role is to be the manager of the secondary application domains, the ones which run the plugin code. This second role allows you to load your plugin code into your new application domains and control the execution of your plugins from unmanaged code.</p>

<p>In my example IDL above <code>Start()</code>, <code>RequestStop()</code> and <code>Stop()</code> are methods that can be called only in secondary application domains and <code>InitialiseDefaultAppDomain()</code> and <code>CreateApplicationInNewAppDomain()</code> must only be made onto the default application domain.</p>

<p><code>InitialiseDefaultAppDomain()</code> is called explicitly just after I start the CLR and set its error escalation policy. It allows me to pass an interface to the managed part of my hosting code that allows it to communicate with the unmanaged part, this interface is pretty simple.<br />
<pre>   [<br />
      object,<br />
      uuid(AFF50626-DDCF-481c-9CE7-0F95B0E9E6D7),<br />
      helpstring("IUnmanagedHost Interface"),<br />
      pointer_default(unique)<br />
   ]<br />
   interface IUnmanagedHost : IHostLog<br />
   {<br />
      HRESULT ShutdownHost();<br />
   }<br />
  <br />
   [<br />
      object,<br />
      uuid(7F153933-8BE3-45b6-B8C5-22B5EFA0B8FD),<br />
      helpstring("IHostLog Interface"),<br />
      pointer_default(unique)<br />
   ]<br />
   interface IHostLog : IUnknown<br />
   {<br />
      HRESULT LogMessage(<br />
         [in] BSTR message);<br />
   }</pre><br />
Strictly for demonstration purposes it allows the managed code to write to the same log file as my unmanaged code and it also allows the managed code to request the unmanaged host shut down. The initialise function also lets me set up event handlers for the default application domain (and for demonstration purposes these event handlers can use the log interface to keep me informed of what's going on).</p>

<p>Loading and running plugin code in the CLR is a two stage process. First I call <code>CreateApplicationInNewAppDomain()</code> on the default <code>AppDomainManager</code> which creates a new application domain and sets it up ready to run the plugin code.<br />
<pre>      int IManagedHost.CreateApplicationInNewAppDomain(<br />
         string appDomainName, <br />
         string applicationName, <br />
         string applicationDirectory, <br />
         string sharedDirectory,<br />
         string configFile,<br />
         int enableShadowCopy)<br />
      {<br />
         if (!defaultAppDomain)<br />
         {<br />
            throw new InvalidOperationException("Should only be called on the default application domain, not on \"" + this.appDomainName + "\"");<br />
         }<br />
  <br />
         if (host == null)<br />
         {<br />
            throw new InvalidOperationException("Not initialised, call InitialiseDefaultAppDomain() first!");<br />
         }<br />
  <br />
         AppDomainSetup setup = new AppDomainSetup();<br />
  <br />
         setup.ApplicationName = applicationName;<br />
         setup.ApplicationBase = ".";<br />
         setup.PrivateBinPath = ".;" + applicationDirectory + ";" + sharedDirectory;<br />
         setup.ConfigurationFile = configFile;<br />
  <br />
         if (enableShadowCopy == 1)<br />
         {<br />
            setup.ShadowCopyFiles = "true";<br />
            setup.CachePath = ".\\Cache\\" + applicationDirectory;<br />
         }<br />
  <br />
         AppDomain appDomain = AppDomain.CreateDomain(appDomainName, null, setup);<br />
  <br />
         ManagedHost manager = (ManagedHost)appDomain.DomainManager;<br />
  <br />
         manager.SetupAppDomain(appDomainName, appDomain, host);<br />
  <br />
         return appDomain.Id;  <br />
      }</pre><br />
Note that once the default <code>AppDomainManager</code> has created a new application domain by calling <code>CreateDomain()</code> it can access the <code>AppDomainManager</code> of the new application domain and, in my case, initialise it. This is similar to what happens with the unmanaged code explicitly initialises the default <code>AppDomainManager</code> by calling <code>InitialiseDefaultAppDomain()</code>. </p>

<p>Once the new application domain has been created I can call <code>Start()</code> on its <code>AppDomainManager</code>, this simply loads the supplied assembly into the new application domain, creates an instance of the type that is the entry point for my application code, calls <code>OnApplicationStart()</code> on it to start the application, and returns interface to the application to unmanaged code so that it can be manipulated from there.<br />
<pre>      IManagedApplication IManagedHost.Start(<br />
         string assemblyName,<br />
         string typeName,<br />
         string applicationName)<br />
      {<br />
         if (defaultAppDomain)<br />
         {<br />
            throw new InvalidOperationException("Should only be called on the application domain that was created for application \"" + application + "\", not on the default application domain");<br />
         }<br />
  <br />
         if (appDomainName != applicationName)<br />
         {<br />
            throw new InvalidOperationException("Should only be called on the application domain that was created for application \"" + application + "\", not on \"" + appDomainName + "\"");<br />
         }<br />
  <br />
         Assembly assembly = Assembly.Load(assemblyName);<br />
  <br />
         object obj = assembly.CreateInstance(typeName);<br />
  <br />
         if (obj == null)<br />
         {<br />
            throw new TypeLoadException("Object \"" + typeName + "\" not found in assembly \"" + assemblyName + "\"");<br />
         }<br />
  <br />
         this.application = (IManagedApplicationControl)obj;<br />
  <br />
         return application.OnApplicationStart(applicationName, host);<br />
      }</pre><br />
My application interface looks like this:<br />
<pre>   [<br />
      object,<br />
      uuid(DE2B37FB-190A-4ef9-9CD9-97CE94C3D5FE),<br />
      helpstring("IManagedApplicationControl Interface"),<br />
      pointer_default(unique)<br />
   ]<br />
   interface IManagedApplicationControl : IUnknown<br />
   {<br />
      HRESULT OnApplicationStart(<br />
         [in] BSTR applicationName,<br />
         [in] IHostLog *log,<br />
         [out, retval] IManagedApplication **application);<br />
  <br />
      HRESULT OnApplicationStopRequested();<br />
  <br />
      HRESULT OnApplicationStop();<br />
   };<br />
  <br />
   [<br />
      object,<br />
      uuid(19A68076-9C7E-4981-BE97-949803AEB76F),<br />
      helpstring("IManagedApplication Interface"),<br />
      pointer_default(unique)<br />
   ]<br />
   interface IManagedApplication : IUnknown<br />
   {<br />
      HRESULT OnConnectionEstablished(<br />
         [in] ISocket *socket);<br />
  <br />
      HRESULT OnReadCompleted(<br />
         [in] SAFEARRAY( BYTE ) data,<br />
         [in] ISocket *socket);<br />
  <br />
      HRESULT OnConnectionClientClose(<br />
         [in] ISocket *socket);<br />
   };</pre><br />
The <code>IManagedApplicationControl</code> interface is used from within the custom <code>AppDomainManager</code> and allows it to start and stop the application. The <code>IManagedApplication</code> interface represents the interface that is presented to the unmanaged code. In this simple server example we pass some network events through from the unmanaged server host.</p>

<p>The simple example implementation looks something like this.<br />
<pre>   class ManagedApplication : IManagedApplicationControl, IManagedApplication<br />
   {<br />
      private string name;<br />
 <br />
      private IHostLog log;<br />
 <br />
      private void LogMessage(string message)<br />
      {<br />
         log.LogMessage(name + ": " + message);<br />
      }<br />
 <br />
      IManagedApplication IManagedApplicationControl.OnApplicationStart(<br />
         string applicationName, <br />
         IHostLog log)<br />
      {<br />
         this.name = applicationName;<br />
 <br />
         this.log = log;<br />
 <br />
         LogMessage("OnApplicationStart");<br />
 <br />
         return this;<br />
      }<br />
 <br />
      void IManagedApplicationControl.OnApplicationStopRequested()<br />
      {<br />
         LogMessage("OnApplicationStopRequested");<br />
      }<br />
 <br />
      void IManagedApplicationControl.OnApplicationStop()<br />
      {<br />
         LogMessage("OnApplicationStop");<br />
      }<br />
 <br />
      void IManagedApplication.OnConnectionEstablished(<br />
         ISocket socket)<br />
      {<br />
         socket.WriteString("Welcome to CLR echo server: " + name + "\r\n");<br />
 <br />
         socket.Read();<br />
      }<br />
 <br />
      void IManagedApplication.OnReadCompleted(<br />
         byte[] data,<br />
         ISocket socket)<br />
      {<br />
          socket.Write(data);<br />
 <br />
          socket.Read();<br />
      }<br />
 <br />
      void IManagedApplication.OnConnectionClientClose(<br />
         ISocket socket)<br />
      {<br />
         LogMessage("OnConnectionClientClose");<br />
      }<br />
   }</pre><br />
As network events occur the are passed through to the appropriate managed application which can deal with them. The unmanaged side of the call is simply a COM method call on an <code>IManagedApplication</code> instance.</p>

<p>I have two ways to stop an application. Firstly I can call <code>IManagedApplicationControl::Stop()</code> from the applications <code>AppDomainManager</code>. I call this just before I unload the application domain, the idea being that it allows the plugin code to clean up before it is destroyed. Secondly I can call <code>IManagedApplicationControl::RequestStop()</code>, this exists so that my hosting code can demonstrate immediate application domain clear down and 'once all existing connections have completed' application domain clear down. With plugin code that is accessed via network users you may want to restart an application (to upgrade it, for example) whilst there are existing users connected and allow those existing users to continue using the old application until they disconnect, OR you might want to just forcibly abort any existing connections and restart the application domain immediately. I call <code>IManagedApplicationControl::RequestStop()</code> if I'm going to allow the application domain to run until existing users have disconnected, this allows the managed application to react accordingly, such as suggesting to the users that they log off, or whatever.</p>

<p>Once I've decided to stop an application and all existing connections have terminated the <code>AppDomain</code> can be unloaded. I do this by calling <code><a href="http://msdn.microsoft.com/en-us/library/ms164417.aspx">ICLRRuntimeHost::UnloadAppDomain()</a></code> and passing it the ID that was returned when we created the new application domain.</p>

<p>That's pretty much it as far as the interface between managed and unmanaged code is concerned. However, the story doesn't end there, on the unmanaged side there's quite a lot going on to allow us to dynamically load and unload managed applications whilst giving the option of allowing existing connections to complete before the application domain that they're running in is terminated, but I'll deal with that next time...</p>

<p> </p>]]>

<![CDATA[<p><map name="google_ad_map_100729182703">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100729182703?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100729182703" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100729182703&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000916.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000916.html">06:27 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=916" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_clr_hosting.html">CLR Hosting</a>
, <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>



</description>


<dc:subject>Socket Servers</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-07-29T18:27:03+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000915.html">
<title>CLR Hosting - .Net 4.0, .Net 2.0, take your pick </title>
<link>http://www.lenholgate.com/archives/000915.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000915.html">12:58 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=915" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>

<![CDATA[<p>I've recently been adjusting my CLR hosting code as a client wanted to be able to host the .Net 4.0 runtime. Previously they were hosting the 2.0 runtime and, as I mentioned <a href="http://www.lenholgate.com/archives/000884.html">a while back</a>, the hosting API has changed with 4.0.</p>

<p>Switching to hosting 4.0 was easy enough but being able to fall back to hosting 2.0 on a machine where 4.0 wasn't installed is slightly more complex. It's reasonably obvious (you need to make sure that you call <code>GetProcAddress()</code> to bind to <code>CLRCreateInstance()</code> rather than linking to it at build time), but Brad Wilson has a nice list of steps to show how it's done <a href="http://bradwilson.typepad.com/blog/2010/04/selecting-clr-version-from-unmanaged-host.html">here</a> on his blog.</p>

<p>There still seems to be some complexity with regards to selecting the most appropriate version of the CLR for a given assembly as whilst <code>ICLRMetaHost::GetVersionFromFile()</code> will, for example, give you "v1.0.3705" for a CLR 1.0 assembly and "v1.1.4322" for a CLR 1.1 assembly which is fine but <code>ICLRMetaHost::GetRuntime()</code> wont apply any machine policies to give you a v2.0 or whatever CLR if you ask it for v1.0.3705 and it's not installed.</p>

<p>I'm probably missing something in the API somewhere and it's not really that much of a problem for me right now, I already have a version munging stage which allows things like "v2.0" to mean 'the latest greatest v2.0 you have please (purely for when the next version comes out and the build is changing with the betas...) and which can be told to default to the latest CLR available if the specified one isn't found, or to fail the request, etc.</p>]]>


<![CDATA[<p><map name="google_ad_map_100727125848">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100727125848?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100727125848" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100727125848&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000915.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000915.html">12:58 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=915" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>



</description>


<dc:subject>Socket Servers</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-07-27T12:58:48+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000914.html">
<title>Tool lag</title>
<link>http://www.lenholgate.com/archives/000914.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000914.html">11:02 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=914" >Comments (6)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>
, <a href="http://www.lenholgate.com/archives/cat_rants.html">Rants</a>

	</div>]]>

<![CDATA[<p>One of the problems of having a collection of tools that interoperate is that there's often a lag between when a tool will interoperate with the latest version of another tool. I'm hardly a bleeding-edge tool junky, I wait until RTM before I start using the latest Visual Studio on a daily basis, and in the case of VC 6 I stuck with it (as did most of my clients) until VS2005 came out and actually improved life for unmanaged C++ development... However, it seems that some tools take a long long time to catch up with Visual Studio. Take DevPartner Studio, for example, it seems that it's always lagging by just enough that I spend more time using it in my "legacy" compiler builds than I do in my day to day builds. It's cool that it works on x64 now but it's less cool that I have to use VS2005 or VS2008 to use it...</p>

<p>The problem with tools that lag is that no matter how useful they are the lag and the lack of daily use affects the usefulness of the tool and that always gets evaluated when I have to pay more money for another year of 'support'... </p>

<p>When a tool isn't in the tool box that you use daily you tend to use it less often than you should... Yes, the reason for this rant is that I've just found a couple of leaks with DevPartner that lived a little longer than they should because I'm developing the code in VS2010 and DevPartner isn't there in the toolbar nagging at me to use it. And, yes I know that I'm the one at fault for not using the tool anyway even though it's easier to ignore right now...</p>

<p>This kind of thing usually isn't actually too much of a problem for me as using these kinds of tools is on my release check-list but as I get clients that only want VS2010 builds it gets more likely that the tool lag will bite.</p>

<p>So, in summary, a version of DevPartner Studio for Visual Studio 2010 would be nice and, even better, if you can't ship with the RTM of the compiler then a roadmap that gives a hint about when you might ship, or even a hand wavey indication of an intention to ship, would be nice...</p>]]>


<![CDATA[<p><map name="google_ad_map_100727110206">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100727110206?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100727110206" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100727110206&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000914.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000914.html">11:02 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=914" >Comments (6)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>
, <a href="http://www.lenholgate.com/archives/cat_rants.html">Rants</a>

	</div>]]>



</description>


<dc:subject>Geek Speak</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-07-27T11:02:06+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000913.html">
<title>Practical Testing: 26 - More functionality, more refactoring and a new bug</title>
<link>http://www.lenholgate.com/archives/000913.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000913.html">09:56 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=913" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>

<![CDATA[<p>Previously on <a href="http://www.lenholgate.com/archives/000306.html">"Practical Testing"</a>... To deal with some specific usage scenarios of a piece of general purpose code I'm in the process of implementing a <a href="http://www.lenholgate.com/archives/000909.html">timer wheel</a> that matches the interface to the timer queue that I previously developed in this <a href="http://www.lenholgate.com/archives/000306.html">series of articles</a>. The timer wheel trades space for speed and so far the development has gone well as I've been able to use the tests that I had already developed for the previous implementations to guide the new development.</p>

<p>By the end of <a href="http://www.lenholgate.com/archives/000911.html">last time</a> we'd got to the point where we had four functions left to implement...</p>]]>
<![CDATA[<p>Today we'll deal with the second style of <code>SetTimer()</code> call. The timers can be set in two ways, the first is useful if you need to repeatedly set and reset a timer, you create a timer handle by calling <code>CreateTimer()</code> and you can then call <code>SetTimer()</code> and <code>CancelTimer()</code> as often as you like. Finally you call <code>DestroyTimer()</code> when you're done with your timer. The second style is for when you simply want to 'fire and forget' a timer. You simply call the second variation of <code>SetTimer()</code> and this creates a timer for you, sets it and destroys it once the timer has timed out or when the timer system is destroyed. This second style of timer makes it easy for the caller and slightly more complex for the timer system since there are now timers that need to be cleaned up once they expire. However, we need to deal with this kind of thing anyway as a timer could be destroyed during timeout processing, or in the gap between a begin/handle/end sequence of timer handling.</p>

<p>Whilst adjusting the tests to make sure they took into account the timer wheel's traits and generally worked correctly with the new implementation I decided that although I like my tests rigid (some would say <a href="http://www.lenholgate.com/archives/000910.html">brittle</a>, or fragile), I'd gone slightly too far with the logging coming out of the tick count providers. These were reporting the value of the tick count that was being provided as well as the fact that the call was made. Now in some of my tests this is useful but here the test was clearly setting the value so logging it was of no use and made the tests more complex in the presence of variable timer granularities. Adjusting the mocks and the tests makes them a bit cleaner.</p>

<p>The tests also needed adjusting now that all of the code can be built with monitoring enabled. The <a href="http://www.lenholgate.com/archives/000910.html">traits</a> work pretty well for this and I'm happy with the results.</p>

<p>There's still quite a bit of duplicate code in the tests and the code to create and set a timer is one piece that's easy to slim down by using the helper function that is used by some but not all of the tests. Only the tests that are actually for <code>SetTimer()</code> need to do it long hand to make it clear what we're actually testing.</p>

<p>Since we now have timers that can delete themselves and since I <a href="http://www.lenholgate.com/archives/000906.html">recently added to the timer monitoring interface</a> to allow us to ensure that all timers were always cleaned up it seems about the right time to add monitoring interface support to the timer wheel.</p>

<p>The resulting changes to implement the second <code>SetTimer()</code> overload are as follows, note that I've adjusted <code>CreateTimer()</code> so that the common code that I need to call when I create a timer in <code>SetTimer()</code> isn't duplicated. The timer data constructor that we're using there sets the timer up appropriately for single use mode.<br />
<pre>CCallbackTimerWheel::Handle CCallbackTimerWheel::CreateTimer()<br />
{<br />
   TimerData *pData = new TimerData();<br />
  <br />
   return OnTimerCreated(pData);<br />
}</p>

<p>CCallbackTimerWheel::Handle CCallbackTimerWheel::OnTimerCreated(<br />
   TimerData *pData)<br />
{<br />
   m_handles.insert(pData);<br />
  <br />
#if (JETBYTE_PERF_TIMER_WHEEL_MONITORING_DISABLED == 0)<br />
  <br />
   m_monitor.OnTimerCreated();<br />
  <br />
#endif<br />
  <br />
   return reinterpret_cast<Handle>(pData);<br />
}</p>

<p>bool CCallbackTimerWheel::SetTimer(<br />
   const Handle &handle,<br />
   Timer &timer,<br />
   const Milliseconds timeout,<br />
   const UserData userData)<br />
{<br />
   if (timeout > m_maximumTimeout)<br />
   {<br />
      throw CException(<br />
         _T("CCallbackTimerWheel::SetTimer()"), <br />
         _T("Timeout is too long. Max is: ") + ToString(m_maximumTimeout) + _T(" tried to set: ") + ToString(timeout));<br />
   }<br />
  <br />
   TimerData &data = ValidateHandle(handle);<br />
  <br />
   const bool wasPending = data.CancelTimer();<br />
  <br />
   data.UpdateData(timer, userData);<br />
  <br />
   InsertTimer(timeout, data, wasPending);<br />
  <br />
#if (JETBYTE_PERF_TIMER_WHEEL_MONITORING_DISABLED == 0)<br />
  <br />
   m_monitor.OnTimerSet(wasPending);<br />
  <br />
#endif<br />
  <br />
   return wasPending;<br />
}<br />
  <br />
void CCallbackTimerWheel::SetTimer(<br />
   IQueueTimers::Timer &timer,<br />
   const Milliseconds timeout,<br />
   const IQueueTimers::UserData userData)<br />
{<br />
   if (timeout > m_maximumTimeout)<br />
   {<br />
      throw CException(<br />
         _T("CCallbackTimerWheel::SetTimer()"), <br />
         _T("Timeout is too long. Max is: ") + ToString(m_maximumTimeout) + _T(" tried to set: ") + ToString(timeout));<br />
   }<br />
  <br />
   TimerData *pData = new TimerData(timer, userData);<br />
  <br />
   OnTimerCreated(pData);<br />
  <br />
   InsertTimer(timeout, *pData);<br />
  <br />
#if (JETBYTE_PERF_TIMER_WHEEL_MONITORING_DISABLED == 0)<br />
  <br />
   m_monitor.OnOneOffTimerSet();<br />
  <br />
#endif<br />
}</pre><br />
So that we can delete these "one shot" timers when the timer wheel is destroyed we need to keep the handle in the handle map, this does, however, open a hole in our handle validation code as someone could pass in a random invalid handle value that matches one of the "one shot" timers and convince the timer wheel that the handle is valid. To prevent this we now also check that the handle isn't scheduled to be deleted after the timer expires, the only handles in the handle map that will be set like this are the "one shot" timers and these, by definition, don't have a valid handle that you can manipulate.<br />
<pre>CCallbackTimerWheel::TimerData &CCallbackTimerWheel::ValidateHandle(<br />
   const Handle &handle) const<br />
{<br />
   TimerData *pData = reinterpret_cast<TimerData *>(handle);<br />
  <br />
   Handles::const_iterator it = m_handles.find(pData);<br />
  <br />
   if (it == m_handles.end())<br />
   {<br />
      throw CException(<br />
         _T("CCallbackTimerWheel::ValidateHandle()"), <br />
         _T("Invalid timer handle: ") + ToString(handle));<br />
   }<br />
  <br />
   if (pData->DeleteAfterTimeout())<br />
   {<br />
      throw CException(<br />
         _T("CCallbackTimerWheel::ValidateHandle()"), <br />
         _T("Invalid timer handle: ") + ToString(handle));<br />
   }<br />
  <br />
   return *pData;<br />
}</pre><br />
With all of that done and with some more tests passing I'm left with just the <code>BeginTimeoutHandling()</code>, <code>HandleTimeout()</code>,  <code>EndTimeoutHandling()</code> code to implement. Unfortunately there's a bug in our timer setting code for the timer wheel and the existing tests don't catch it.</p>

<p><img alt="TimerWheel-3.png" src="http://www.lenholgate.com/archives/images/TimerWheel-3.png" width="434" height="301" border="0" /></p>

<p>Let's assume that we're in the situation shown above and we set a timer. The timer wheel has its current time set to 35ms before the actual time because timeouts haven't been handled yet. At present if we set a timer for 10ms the timer will be set at the point marked as 30 on the diagram above rather than at the point marked 65. The existing tests don't show this problem as they all set timers for a 'now' that is the same as the time the wheel was created or just after timeouts have been handled; which means that current always equals now in most of the tests that set timers. A new test that sets a timer with now != current clearly shows the problem. I'll leave this broken test to show me the way for next time.</p>

<p>The code can be found <a href="http://lenholgate.com/archives/zips/PracticalTesting-26.zip">here</a> and the <a href="http://www.lenholgate.com/archives/000906.html">previous rules</a> apply.</p>]]>

<![CDATA[<p><map name="google_ad_map_100723095601">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100723095601?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100723095601" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100723095601&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000913.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000913.html">09:56 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=913" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>



</description>


<dc:subject>Testing</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-07-23T09:56:01+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000912.html">
<title>Amusing bug in GetTempPath()</title>
<link>http://www.lenholgate.com/archives/000912.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000912.html">10:14 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=912" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>
, <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>

<![CDATA[<p>Yesterday I had a bug report from a client who had a user that was getting an exception report from their software which simply said "GetTempPath() - Failed to get temp path". Now as error messages go this isn't the best but it comes from some code that has been in my tools libraries for around 10 years and which has never failed before, it has no tests, we're probably lucky that the message didn't just read "TODO" as I'm pretty sure that it's the first time that anyone has ever seen it apart from by reading my source code or running <a href="http://technet.microsoft.com/en-gb/sysinternals/bb897439.aspx">strings</a> on an exe that includes my source code... Anyway...</p>

<p>The offending code was a wrapper around the operating system function <code><a href="http://msdn.microsoft.com/en-us/library/aa364992(VS.85).aspx">GetTempPath()</a></code>. I always tend to wrap these kinds of things so that I can convert errors to exceptions (I did a good job of that here didn't I) and so that I can convert types to the kind of types that I prefer to use. In this case I also dealt with the fact that you need to call the API without a buffer to determine how big a buffer it requires and then call it again with the correct sized buffer to obtain the path.</p>

<p><code><a href="http://msdn.microsoft.com/en-us/library/aa364992(VS.85).aspx">GetTempPath()</a></code> is a simple function and the documentation is pretty clear on how it should be used.  My original wrapper was fairly crap.<br />
<pre>_tstring GetTempPath()<br />
{<br />
   const DWORD spaceRequired = ::GetTempPath(0, 0);      // 1<br />
  <br />
   _tstring directory;<br />
  <br />
   directory.resize(spaceRequired - 1);     // 2<br />
  <br />
   const DWORD spaceUsed = 1 + ::GetTempPath(spaceRequired, const_cast<TCHAR*>(directory.c_str()));    // 3<br />
  <br />
   if (spaceRequired != spaceUsed)   // 4<br />
   {<br />
      throw CException(_T("GetTempPath()"), _T("Failed to get temp path"));<br />
   }<br />
  <br />
   return directory;<br />
}</pre><br />
First I called the function to determine the required size, note that the required "size is the size of the buffer in <code>TCHAR</code>s" needed, which includes the terminating null character. Next I created a string that was the correct size (note that I'm removing 1 because the required size includes space for the null and I'm resizing the data area of the string and the null is added on for me. Thirdly I call the API again with my buffer. I then check that the second call uses all of the space that I allocated in the first call and fail if it doesn't.</p>

<p>There's quite a lot wrong with this code but mostly it will work... The check at stage 4 is overly restrictive but shouldn't pose a problem, except that it does... If your temp path contains an unnecessary double backslash; <code>C:\\temp</code> for example rather that <code>C:\temp</code> then the first call will return the length including the double backslash and the second call will return the path with the unnecessary backslash removed. This means that for the example path shown above, the second call returns <code>spaceRequired - 2</code> rather than the expected <code>spaceRequired - 1</code> and the code fails with the rather useless error message.</p>

<p>The fixed version of the code doesn't suffer from this problem.<br />
<pre>_tstring GetTempPath()<br />
{<br />
   const DWORD spaceRequired = ::GetTempPath(0, 0);<br />
  <br />
   if (spaceRequired == 0)<br />
   {<br />
      const DWORD lastError = GetLastError();<br />
  <br />
      throw CWin32Exception(_T("GetTempPath()"), lastError);<br />
   }<br />
  <br />
   _tstring directory;<br />
  <br />
   directory.resize(spaceRequired - 1);<br />
  <br />
   const DWORD spaceUsed = ::GetTempPath(spaceRequired, const_cast<TCHAR*>(directory.c_str()));<br />
  <br />
   if (spaceUsed == 0)<br />
   {<br />
      const DWORD lastError = GetLastError();<br />
  <br />
      throw CWin32Exception(_T("GetTempPath()"), lastError);<br />
   }<br />
  <br />
   if (spaceUsed >= spaceRequired)<br />
   {<br />
      throw CException(<br />
         _T("GetTempPath()"), <br />
         _T("Failed to get temp path, second call needed more space ") + ToString(spaceUsed + 1) + <br />
         _T(" than first call allocated ") + ToString(spaceRequired));<br />
   }<br />
  <br />
   directory.resize(spaceUsed);<br />
  <br />
   return directory;<br />
}</pre><br />
Whilst there are still, no doubt, style issues, this version checks for errors in a better way (I'd first thought that the failure was some kind of permissions thing) and reports these errors in a clearer manner. Hopefully it will be another 10 years at least before I get another error report for this piece of code.</p>

<p>This fix will be included in version 6.3 of the server framework code which currently has no scheduled release date. </p>]]>


<![CDATA[<p><map name="google_ad_map_100722101412">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100722101412?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100722101412" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100722101412&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000912.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000912.html">10:14 AM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=912" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_geek_speak.html">Geek Speak</a>
, <a href="http://www.lenholgate.com/archives/cat_socket_servers.html">Socket Servers</a>

	</div>]]>



</description>


<dc:subject>Socket Servers</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-07-22T10:14:12+00:00</dc:date>
</item>
<item rdf:about="http://www.lenholgate.com/archives/000911.html">
<title>Practical Testing: 25 - Nothing is free</title>
<link>http://www.lenholgate.com/archives/000911.html</link>
<description>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000911.html">02:13 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=911" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>

<![CDATA[<p>I'm in the process of implementing a <a href="http://www.lenholgate.com/archives/000909.html">timer wheel</a> that matches the interface to the timer queue that I previously developed in this <a href="http://www.lenholgate.com/archives/000306.html">series of articles</a>. The idea being that for certain specific usage scenarios the timer wheel will perform better than the timer queues. Last time I refactored the tests that I was using for the timer queues to remove duplication and I now have a set of failing tests for the new timer wheel. </p>

<p>As soon as I started to look at making some of the failing tests pass I realised that having a heap of failing tests wasn't such a good idea, at least with my home brew test framework. I had stubbed out the timer wheel's interface and had decided to throw exceptions from the functions that weren't implemented yet. Those exceptions caused the tests that used that functionality to fail, so far so good. Unfortunately there was no differentiation between tests that I knew would fail and tests that just happened to be failing; I discovered this when I realised that some of the failing tests were for the timer queues and not the wheel... Switching the exception thrown to one of my testing exceptions, a "test skipped" exception means that I now have a load of timer wheel tests that are skipped due to lack of implementation code and the test failures are clearly failures. Once the real failures were fixed I could move on with the new code.  </p>]]>
<![CDATA[<p>The great thing about a timer wheel is that it has O(1) performance for setting a timer, simply index into the array and push the new timer onto the head of the list of other timers at this time. It also has O(1) timer cancellation; each timer knows where it is in the wheel and can unset itself directly. For many uses timeout handling can be O(1) as well, if your timer handling code runs from a hardware timer tick then each tick moves the wheel forward by one slot and expires the timers that are present there. My usage is a little more complicated in that I need to be able to query the wheel for the time when the next timer is due. This means that I need to look up when the next timer is due and to do that I need to scan the wheel from 'now' forward until I find a timer... Our worst case is O(n slots) where the number of slots is determined by the maximum supported timeout and the timer granularity.</p>

<p><img alt="TimerWheel-1.png" src="http://www.lenholgate.com/archives/images/TimerWheel-1.png" width="434" height="301" border="0" /></p>

<p>In the diagram above, if the timer wheel's current time is 0 then we would need to scan forward sequentially from 'start' to the first timer that is set at position 30 to determine that the first timer is set at 30...</p>

<p>It's possible to optimise this. We could manage a 'hint' which points to the earliest timer that has been set, discovering the next timeout could then be O(1) if the hint is set. The hint could be managed by our calls to <code>SetTimer()</code>, if the timer we're setting is earlier than the hint, or if it's the first timer set then we set the hint to point at it. Unfortunately this scheme falls down in the presence of timer cancellation. If you cancel the earliest timer then you need to scan forward to update the hint, this forward scan is potentially O(n); so now your cancellation has gone from O(1) to O(n) to keep your timeout processing at O(1)... In some usage scenarios this might be acceptable except that, of course, expiring a timer or setting a timer that is already set are also forms of cancellation...</p>

<p>For now we'll avoid all of this complexity and settle for O(n) next timeout calculation. We will, however, mitigate the worst case and add a counter that counts how many timers are currently set, if the counter is zero then there's no need to scan the whole array to discover that no timer is set; our worst case is now that only one timer is set and it's set to the maximum timeout value. Likewise we can keep a hint that can be passed from one call to <code>GetNextTimeout()</code> to the next as long as the hint is zeroed upon any timer changes.<br />
<pre>Milliseconds CCallbackTimerWheel::GetNextTimeout()<br />
{<br />
   Milliseconds nextTimeout = INFINITE;<br />
  <br />
   // We need to work out the time difference between now and the first timer that is set. <br />
  <br />
   if (!m_pFirstTimerSetHint)<br />
   {<br />
      m_pFirstTimerSetHint = GetFirstTimerSet(); <br />
   }<br />
  <br />
   if (m_pFirstTimerSetHint)<br />
   {<br />
      // A timer is set! Calculate the timeout in ms<br />
  <br />
      nextTimeout = static_cast<Milliseconds>(((m_pFirstTimerSetHint > m_pNow ? (m_pFirstTimerSetHint - m_pNow) : (m_pNow - m_pFirstTimerSetHint)) + 1) * m_timerGranularity);<br />
  <br />
      const Milliseconds now = m_tickCountProvider.GetTickCount();<br />
  <br />
      if (now != m_currentTime)<br />
      {<br />
         // Time has moved on, adjust the next timeout to take into account the difference between now and <br />
         // the timer wheel's view of the current time...<br />
  <br />
         const Milliseconds timeDiff = (now > m_currentTime ? now - m_currentTime : m_currentTime - now);<br />
  <br />
         if (timeDiff > nextTimeout)<br />
         {<br />
            nextTimeout = 0;<br />
         }<br />
         else<br />
         {<br />
            nextTimeout -= timeDiff;<br />
         }<br />
      }<br />
   }<br />
  <br />
   return nextTimeout;<br />
}<br />
  <br />
CCallbackTimerWheel::TimerData **CCallbackTimerWheel::GetFirstTimerSet() const<br />
{<br />
   TimerData **pFirstTimer = 0;<br />
  <br />
   if (m_numTimersSet != 0)<br />
   {<br />
      // Scan forwards from now to the end of the array...<br />
  <br />
      for (TimerData **p = m_pNow; !pFirstTimer && p < m_pTimersEnd; ++p)<br />
      {<br />
         if (*p)<br />
         {<br />
            pFirstTimer = p;<br />
         }<br />
      }<br />
  <br />
      if (!pFirstTimer)<br />
      {<br />
         // We havent yet found our first timer, now scan from the start of the array to <br />
         // now...<br />
  <br />
         for (TimerData **p = m_pTimersStart; !pFirstTimer && p < m_pNow; ++p)<br />
         {<br />
            if (*p)<br />
            {<br />
               pFirstTimer = p;<br />
            }<br />
         }<br />
      }<br />
  <br />
      if (!pFirstTimer)<br />
      {<br />
         throw CException(_T("CCallbackTimerWheel::GetFirstTimerSet()"), _T("Unexpected, no timer set but count = ") + ToString(m_numTimersSet));<br />
      }<br />
   }<br />
  <br />
   return pFirstTimer;<br />
}</pre></p>

<p>Now that we can work out when the next timeout is due we can start to think about handling the timers when they expire. Given the diagram below, if the timer wheel believes that the current time is as indicated and the timers are then expired when the time is at 'now' we will need to process all of the the timers that are set in the order shown by their index numbers.</p>

<p><img alt="TimerWheel-3.png" src="http://www.lenholgate.com/archives/images/TimerWheel-3.png" width="434" height="301" border="0" /></p>

<p>Again, if we were driving the wheel from a timer tick then things are simplified as we would only ever 'rotate' the wheel by one slot at a time. In the world of general purpose, multi-threaded, non-real time systems though (is that a big enough proviso?) all manner of reasons might mean that we don't actually get to process the timers until after they're due.</p>

<p>If all we need to worry about is processing the timers in sequence then we could step along the wheel and then walk each chain of timers and handle them as we go. It could be a little more complex than that if we want to use the <code>BeginTimeoutHandling()</code>, <code>HandleTimeouts()</code>, <code>EndTimeoutHandling()</code> methods to allow us to process timers without holding our lock onto the timer system whilst the timers are dispatched (I talk about why this is a desirable design <a href="http://www.lenholgate.com/archives/000795.html">here</a>, and why needing to go through the begin, handle, end sequence multiple times to process timers is less than ideal <a href="http://www.lenholgate.com/archives/000907.html">here</a>). Ideally, for the later situation we'd want our 'begin' to accumulate all 6 timers into a correctly ordered list and remove them from the wheel. We would then unlock the wheel and process the 6 timers in order before locking the wheel again to update the processed timers inside of <code>EndTimeoutHandling()</code>. Doing it this way would mean traversing each slot's list of timers to get to the last one so that we can link the next list onto the end of the previous lists...</p>

<p>If we ignore the more complex scenario and implement the easy one we end up with code like this to deal with the 'holding a lock whilst dispatching' case.<br />
<pre>void CCallbackTimerWheel::HandleTimeouts()<br />
{<br />
   const Milliseconds now = m_tickCountProvider.GetTickCount();<br />
  <br />
   while (TimerData *pTimers = GetTimersToProcess(now))<br />
   {<br />
      while (pTimers)<br />
      {<br />
         pTimers = pTimers->OnTimer();<br />
  <br />
         --m_numTimersSet;<br />
      }<br />
   }<br />
}<br />
  <br />
CCallbackTimerWheel::TimerData *CCallbackTimerWheel::GetTimersToProcess(<br />
   const Milliseconds now)<br />
{<br />
   TimerData *pTimers = 0;<br />
  <br />
   // Round 'now' down to the timer granularity<br />
  <br />
   const Milliseconds thisTime = ((now / m_timerGranularity) * m_timerGranularity);<br />
  <br />
   while (!pTimers && m_currentTime != thisTime)<br />
   {<br />
      TimerData **ppTimers = GetTimerAtOffset(0);<br />
  <br />
      pTimers = *ppTimers;<br />
  <br />
      // Step along the wheel...<br />
  <br />
      m_pNow++;<br />
  <br />
      if (m_pNow >= m_pTimersEnd)<br />
      {<br />
         m_pNow = m_pTimersStart + (m_pNow - m_pTimersEnd);<br />
      }<br />
  <br />
      m_currentTime += m_timerGranularity;<br />
   }<br />
  <br />
   if (pTimers)<br />
   {<br />
      m_pFirstTimerSetHint = 0;<br />
   }<br />
  <br />
   return pTimers;<br />
}</pre><br />
With this in place we're left with 20 tests that fail due to lack of implementation and 4 functions that we need to deal with properly. Three form the begin, handle, end API for unlocked timer dispatch and the fourth is for the the <code>SetTimer()</code> overload that doesn't require a handle. There's an interesting amount of functionality required to implement the remaining functions as you can see from <a href="http://www.lenholgate.com/archives/000795.html">here</a> and <a href="http://www.lenholgate.com/archives/000803.html">here</a>. We'll look at this next time.</p>

<p>The code can be found <a href="http://lenholgate.com/archives/zips/PracticalTesting-25.zip">here</a> and the <a href="http://www.lenholgate.com/archives/000906.html">previous rules</a> apply.</p>]]>

<![CDATA[<p><map name="google_ad_map_100721141357">
<area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/100721141357?pos=0" coords="1,2,367,28"/>
<area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map>
<img usemap="#google_ad_map_100721141357" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-6888952347469638&amp;channel=6581658359&amp;output=png&amp;cuid=100721141357&amp;url=http%3A%2F%2Fwww.lenholgate.com%2Farchives%2F000911.html"/></p>]]>

<![CDATA[<div class="posted">Posted by Len at <a href="http://www.lenholgate.com/archives/000911.html">02:13 PM</a>
		| <a href="http://www.lenholgate.com/mt/mt-comments-5.cgi?entry_id=911" >Comments (0)</a>
	
	
| Categories: <a href="http://www.lenholgate.com/archives/cat_source_code.html">Source Code</a>
, <a href="http://www.lenholgate.com/archives/cat_testing.html">Testing</a>

	</div>]]>



</description>


<dc:subject>Testing</dc:subject>
<dc:creator>Len</dc:creator>
<dc:date>2010-07-21T14:13:57+00:00</dc:date>
</item>


</rdf:RDF>