<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>Chris Suter&apos;s Blog</title>
        <link>http://sutes.co.uk/</link>
        <description></description>
        <language>en-US</language>
        <copyright>Copyright 2010</copyright>
        <lastBuildDate>Thu, 17 Dec 2009 06:00:06 +1000</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>NSURLConnection &amp; Using HEAD Method</title>
            <description><![CDATA[<p>If you want to use the HEAD method with NSURLConnection, it&#8217;s simple, you use <code>-[NSMutableURLRequest setHTTPMethod:]</code>.</p>

<p>However, you need to be careful with redirects. Redirections will revert to using the GET method which usually isn&#8217;t what you want, so you need something like:</p>

<blockquote><code><pre>
- (NSURLRequest *)connection:(NSURLConnection *)connection
             willSendRequest:(NSURLRequest *)request
            redirectResponse:(NSURLResponse *)redirectResponse
{
    if ([[request HTTPMethod] isEqualTo:@"HEAD"])
        return request;

    NSMutableURLRequest *newRequest = [request mutableCopy];
    [newRequest setHTTPMethod:@"HEAD"];

    return [newRequest autorelease];
}
</pre></code></blockquote>

<p>I suspect that this bug report is invalid: <a href="http://openradar.appspot.com/7019347">http://openradar.appspot.com/7019347</a>.</p>
]]></description>
            <link>http://sutes.co.uk/2009/12/nsurlconnection-using-head-met.html</link>
            <guid>http://sutes.co.uk/2009/12/nsurlconnection-using-head-met.html</guid>
            
            
            <pubDate>Thu, 17 Dec 2009 06:00:06 +1000</pubDate>
        </item>
        
        <item>
            <title>x86_64 Assembler</title>
            <description><![CDATA[<p>I&#8217;m OK at deciphering PowerPC assembler and i386 assembler but now it&#8217;s all x86_64. If you&#8217;re having a look at the internals of AppKit in x86_64, you need to print out page 21 of this: <a href="http://www.x86-64.org/documentation/abi.pdf">http://www.x86-64.org/documentation/abi.pdf</a> and stick it on your wall next to your C operator precedence table.</p>

<p>Now wherever you see objc_msgSend (or something similar), the selector gets passed in $rsi. To find out what it is, type:</p>

<blockquote><code>p (char *)sel_getName($rsi)</code></blockquote>

<p>x86_64 comes with instruction pointer relative addressing so you might notice that gdb helpfully displays what the target address is wherever it&#8217;s used. So if you&#8217;re looking at some assembler that looks like this:</p>

<blockquote style="font-size:75%"><code>
0x00007fff811f33fc <-[NSTableView reloadData]+115>: mov    -0x10f16b8b(%rip),%rsi        # 0x7fff702dc878<br/>
0x00007fff811f3403 <-[NSTableView reloadData]+122>: mov    %rbx,%rdi<br/>
0x00007fff811f3406 <-[NSTableView reloadData]+125>: callq  0x7fff8184278e &lt;dyld_stub_objc_msgSend&gt;<br/>
</code></blockquote>

<p>You can figure out what the call is by typing:</p>

<blockquote><code>p (char *)sel_getName(*(void **)0x7fff702dc878)</code></blockquote>

<p>And you&#8217;ll see something like:</p>

<blockquote><code>$2 = 0x7fff8187bb68 "_endMyEditing"</code></blockquote>
]]></description>
            <link>http://sutes.co.uk/2009/12/x86-64-assembler.html</link>
            <guid>http://sutes.co.uk/2009/12/x86-64-assembler.html</guid>
            
            
            <pubDate>Fri, 11 Dec 2009 10:58:24 +1000</pubDate>
        </item>
        
        <item>
            <title>Attempt to Pop an Unknown Autorelease Pool</title>
            <description><![CDATA[<p>If you see:</p>

<pre><code>*** attempt to pop an unknown autorelease pool (0x12345678)
</code></pre>

<p>You can debug it by setting a breakpoint in the _CFAutoreleasePoolPop function. To find out exactly where, disassemble the _CFAutoreleasePoolPop function, and look for the first call to CFLog. On the i386 architecture it&#8217;s at _CFAutoreleasePoolPop+84.</p>
]]></description>
            <link>http://sutes.co.uk/2009/11/attempt-to-pop-an-unknown-auto.html</link>
            <guid>http://sutes.co.uk/2009/11/attempt-to-pop-an-unknown-auto.html</guid>
            
            
            <pubDate>Fri, 13 Nov 2009 13:47:34 +1000</pubDate>
        </item>
        
        <item>
            <title>_Block_dump</title>
            <description><![CDATA[<p>If you&#8217;re playing with blocks you can get debug information by using:</p>

<pre><code>char *_Block_dump (block_t block);
</code></pre>

<p>It&#8217;s not in any public header so you&#8217;ll have to declare it yourself. It returns a debug string you can log and will give you the retain count of the block, whether it&#8217;s a global, stack or heap block and other information.</p>
]]></description>
            <link>http://sutes.co.uk/2009/10/-block-dump.html</link>
            <guid>http://sutes.co.uk/2009/10/-block-dump.html</guid>
            
            
            <pubDate>Mon, 19 Oct 2009 17:28:24 +1000</pubDate>
        </item>
        
        <item>
            <title>Hacking</title>
            <description><![CDATA[<p>In my last entry I mentioned the private API <code>_LSSetStrongBindingForRef</code> that Launch Services has to set the application that launches a particular file. I thought it might be interesting to post how I figured it out.</p>

<p>Firstly, I reasoned that Launch Services would probably have a private API that Finder uses to set it. I could have gone through all the symbols that Launch Services exports, including the private ones looking for likely candidates. To do that, you use the nm tool:</p>

<blockquote><code>
 nm /System/Library/Frameworks/CoreServices.framework/ \<br/>
 Versions/A/Frameworks/LaunchServices.framework/LaunchServices
</code></blockquote>

<p>That will spew out a load of information. Any symbols that are tagged <code>U</code>, are undefined which mean they're come from somewhere else--another framework or library. We're interested in symbols that are tagged <code>T</code> since they're symbols that are exported by that framework. Symbols that have a lower case <code>t</code>, are local to the module and aren't exported. Binaries that are stripped shouldn't have any symbols with a lower case codes. Remember that all C symbols will have an underscore at the beginning that you won't see in your code. C++ symbols are a different story that I won't go into here.</p>

<p>OK, so that's one way I could have figured it, but I got bored looking through them all, so...</p>

<p>Since I knew that Finder was able to set the binding, I figured I could just see what Finder does, but how to do that? What I did was attach the debugger (gdb) to Finder and set some breakpoints. To attach the debugger to Finder:</p>

<blockquote><code>gdb /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder<br/>
attach Finder<em>&lt;TAB&gt;</em>
</code></blockquote>

<p>Apple's version of gdb supports tab completion for the attach command so when you press the tab command you should find it fills in the process id of Finder.</p>

<p>Now what to set the breakpoints on? Well, I first tried setting the breakpoint on write--obviously setting the binding is going to involve writing to the disk at some point (I already knew that the binding was set as part of the <code>usro</code> resource in the resource fork) so my idea was that I'd set a breakpoint on write and then set a binding in Finder and see what we got. There aren't actually that many primitives for writing to the disk; all the Cocoa and Carbon frameworks eventually call BSD primitives to do what they want so you usually just need to set breakpoints on write/pwrite. For example, you'll probably find <code>-[NSData writeToFile:atomically:]</code> calls a CoreFoundation function which then calls one of the BSD write functions. </p>

<p>To set a breakpoint:</p>

<blockquote><code>b write</code></blockquote>

<p>Now on my system it sets breakpoints in two places, on <code>write</code> and <code>write$NOCANCEL</code>. That's fine so I just continued. Type <code>c</code> to continue.</p>

<p>OK, those of you playing along at home will find that whilst it might stop in a few places whilst you're trying to set the binding (e.g. when an open panel appears), it doesn't stop after you've actually set the binding. By the way, to continue after hitting a breakpoint, type <code>c</code>.</p>

<p>So then I set a breakpoint on <code>pwrite</code>, and this time, just after setting the binding, the debugger stops. What now? Well, we want a backtrace. To get that, type <code>bt</code> and this is what we get:</p>

<blockquote><code>#0  0x00007fff82b8b03c in pwrite ()<br/>
#1  0x00007fff821b6b1a in BasicWrite ()<br/>
#2  0x00007fff821b6a49 in PBWriteForkSync ()<br/>
#3  0x00007fff821b69d6 in FSWriteFork ()<br/>
#4  0x00007fff822281c0 in WriteData ()<br/>
#5  0x00007fff822282d3 in WrResource ()<br/>
#6  0x00007fff821ca33a in UpdateTheFile ()<br/>
#7  0x00007fff821ca035 in UpdateResFileCommon ()<br/>
#8  0x00007fff8213a028 in _LSSetStrongBindingForRef ()<br/>
</code></blockquote>

<p>It goes on but I stopped at <code>_LSSetStrongBindingForRef</code>. As you can see, there are a bunch of Carbon functions before we get to the <code>pwrite</code> call.</p>

<p>To get the prototype for the function I searched Google and found someone had already done it for me. ;-)</p>

<p>I should note that you'll probably want to detach from Finder: type detach, and then Finder will continue running. If you don't, you'll probably end up killing Finder which isn't actually such a big deal as it'll just be restarted for you.</p>

<p>Anyway, every programmer should get seriously familiar with gdb. In this case, I've used it to discover a private API which I personally wouldn't use and don't recommend others using either, but I have used similar techniques before to debug problems I've had with some of Apple's frameworks, not to mention my own code. I've mentioned the nm command which is useful, but there's also otool which will dump things like what libraries a binary is linked to; there's the awesome <a href="http://www.codethecode.com/projects/class-dump/">class-dump</a> tool; there's fs_usage for monitoring what accesses the disk and lsof for tracking down open files, and then there's dtrace and probably many more that I've forgotten.</p>
]]></description>
            <link>http://sutes.co.uk/2009/10/hacking.html</link>
            <guid>http://sutes.co.uk/2009/10/hacking.html</guid>
            
            
            <pubDate>Thu, 08 Oct 2009 19:47:46 +1000</pubDate>
        </item>
        
        <item>
            <title>Creator Codes Are Not Replaced by Uniform Type Identifiers</title>
            <description><![CDATA[<p>There&#8217;s some <a href="http://forums.appleinsider.com/showthread.php?s=&amp;threadid=103219">press</a> <a href="http://db.tidbits.com/article/10537">about</a> suggesting that Creator Codes are replaced by Uniform Type Identifiers (UTI) which is rubbish.</p>

<p>They&#8217;re not.</p>

<p>Uniform Type Identifiers are just a type. To be able to work out the type of something you have to look at some metadata which for the vast majority of things isn&#8217;t a UTI. For most files on your Mac, it will be the extension of the file that determines what type of file it is. About the only place that you&#8217;ll see a UTI is within the property list of an application where it says what types it supports.</p>

<p>As far as I know, there is no direct replacement for creator codes. There is no other metadata that you can put on the file that tells the system what application created it, and even if there was, UTIs would have little to do with it since UTIs represent types, not applications.</p>

<p>There is metadata on a file that is used to say what application should open the file (on a per file basis). This is stored within the resource fork of the file in a <tt>usro</tt> resource. This simply stores the path of the application (no UTI is involved) that should open a file and yes, this could be used to replace creator codes<del>&#8212;I don&#8217;t know if there&#8217;s an API for setting them, I haven&#8217;t checked.</del> Launch Services has a private API that you could use to set the binding:</p>

<pre><code>extern OSStatus _LSSetStrongBindingForRef(const FSRef *inItemRef,
                                          FSRef *inAppRefOrNil);
</code></pre>

<p>I don&#8217;t know why Apple have got rid of creator codes but it is a shame they haven&#8217;t replaced them with something. Perhaps they haven&#8217;t had time to figure out what to replace them with. Thinking about it, what you probably want is to store the bundle ID of the application that created the file in some metadata somewhere (as an extended attribute or within the resource fork). I haven&#8217;t thought it through, but there might also be security issues with creator codes&#8212;malicious programs could set them behind your back and cause bad stuff to happen.</p>
]]></description>
            <link>http://sutes.co.uk/2009/09/creator-codes-are-not-replaced.html</link>
            <guid>http://sutes.co.uk/2009/09/creator-codes-are-not-replaced.html</guid>
            
            
            <pubDate>Wed, 23 Sep 2009 08:20:32 +1000</pubDate>
        </item>
        
        <item>
            <title>AppleGlot on Snow Leopard</title>
            <description><![CDATA[<p>To get AppleGlot to work properly on Snow Leopard, apply this <a href="/stuff/ibtoolWrapper.patch">patch</a> to <tt>/Developer/Applications/AppleGlot/AppleGlot.app/Contents/Frameworks /AppleGlot.framework/Resources/ibtoolWrapper</tt>.</p>

<p>(It&#8217;s broken because ibtool runs as a 64-bit app. and can&#8217;t load AppleGlot&#8217;s plugin which is 32-bit).</p>
]]></description>
            <link>http://sutes.co.uk/2009/09/appleglot-on-snow-leopard.html</link>
            <guid>http://sutes.co.uk/2009/09/appleglot-on-snow-leopard.html</guid>
            
            
            <pubDate>Tue, 15 Sep 2009 08:26:00 +1000</pubDate>
        </item>
        
        <item>
            <title>Getting hexdump to Give Suitable Output for Use in C</title>
            <description><![CDATA[<p>Here&#8217;s how to get <code>hexdump</code> to give you a suitable output for embedding in a C file:</p>

<blockquote><code><pre>hexdump -e "8/1 \"0x%02x, \" \"\n\"" &lt;file&gt;</pre></code></blockquote>

<p>(This post is for my benefit as much as anyone else.)</p>
]]></description>
            <link>http://sutes.co.uk/2009/02/getting-hexdump-to-give-suitab.html</link>
            <guid>http://sutes.co.uk/2009/02/getting-hexdump-to-give-suitab.html</guid>
            
            
            <pubDate>Wed, 04 Feb 2009 08:15:26 +1000</pubDate>
        </item>
        
        <item>
            <title>Kernel Log Buffer Size</title>
            <description><![CDATA[<p>I&#8217;ve been working on some kernel code recently. The default log buffer size is only 4 KB so it doesn&#8217;t take much before you lose messages (not that I recommend you use logging for debugging purposes, but there are some times when it&#8217;s necessary). Anyway to increase it, you need to set the <tt>msgbuf</tt> boot argument. For example, in Terminal type this:</p>

<blockquote><tt>sudo nvram boot-args=msgbuf=65536</tt></blockquote>
]]></description>
            <link>http://sutes.co.uk/2008/12/kernel-log-buffer-size.html</link>
            <guid>http://sutes.co.uk/2008/12/kernel-log-buffer-size.html</guid>
            
            
            <pubDate>Fri, 05 Dec 2008 21:19:35 +1000</pubDate>
        </item>
        
        <item>
            <title>C++ Operator Overloading</title>
            <description><![CDATA[<p>I came across this code recently:</p>

<p><code><pre>
level = kIOStorageAccessNone;
while ( ( object = objects->getNextObject( ) ) )
{
    if ( object != client )
    {
        level += _openClients->getObject( ( OSSymbol * ) object );
    }
}
</pre></code></p>

<p>Basically, it&#8217;s going through a list of clients that it services and works out what the aggregate access level is for all the clients. Here are the possible access levels:</p>

<p><code><pre>
enum
{
    kIOStorageAccessNone          = 0x00,
    kIOStorageAccessReader        = 0x01,
    kIOStorageAccessReaderWriter  = 0x03,
    kIOStorageAccessSharedLock    = 0x04,
    kIOStorageAccessExclusiveLock = 0x08
};
</pre></code></p>

<p>Now, from looking at this code, it looks wrong because of the use of the <code>+=</code>. Surely <code>|=</code> is more appropriate. It&#8217;s obvious to me now, but it took me some time before I found the bit where they&#8217;d overridden the <code>+=</code> operator:</p>

<p><code><pre>
inline void operator+=( IOStorageAccess access )
{
    _access = ( ( _access - 1 ) >> 1 ) &amp; 7;
    _access = gIOMediaAccessTable[ ( ( access - 1 ) >> 1 ) &amp; 7 ][ _access ];
    _access = ( ( _access &amp; 7 ) &lt;&lt; 1 ) + 1;
}
</pre></code></p>

<p>Anyway, this, in my opinion, is a classic example of an abuse of C++ operator overloading. The rule when writing code should be to make it as readable and as obvious as possible first before you start trying to be clever. If the code had been something like this:</p>

<p><code><pre>
    clientLevel = _openClients->getObject( ( OSSymbol * ) object )->unsigned32BitValue( );
    level = aggregateLevel( level, clientLevel );
</pre></code></p>

<p>it wouldn&#8217;t have cost me any time as it would have been clear what was going on.</p>

<p>It&#8217;s for similar reasons that I always put brackets round expressions that combine <code>&amp;&amp;</code> and <code>||</code> clauses: not everybody knows the order of precedence of these two and it&#8217;s easy to forget; adding brackets means you don&#8217;t need to remember.</p>

<p>For example, I would always do:</p>

<p><code><pre>
    if ((a &amp;&amp; b) || (c &amp;&amp; d))
</pre></code></p>

<p>rather than</p>

<p><code><pre>
    if (a &amp;&amp; b || c &amp;&amp; d)
</pre></code></p>

<p>I know it&#8217;s tempting to use that clever bit of the language that you just learnt about but in doing so you might make it harder for the person that follows you. The general rule should be: unless it is a common idiom, make it clear what&#8217;s going on and if a better known alternative exists, use that instead.</p>
]]></description>
            <link>http://sutes.co.uk/2008/10/c-operator-overloading.html</link>
            <guid>http://sutes.co.uk/2008/10/c-operator-overloading.html</guid>
            
            
            <pubDate>Tue, 28 Oct 2008 19:20:47 +1000</pubDate>
        </item>
        
        <item>
            <title>Disk Arbitration</title>
            <description><![CDATA[<p>Disk Arbitration is what is used on the Mac to handle automatic mounting of volumes and various other disk related things. When you insert a disk, the kernel will instantiate drivers for it and notify the Disk Arbitration daemon. It will then ask filesystem plugins if they recognise the volume and if they do it will usually proceed to mount them.</p>

<p>Using Disk Arbitration, you can send requests to eject disks, mount and unmount volumes, rename volumes and you can claim a disk for exclusive use. For each of those operations you can also approve or reject requests that other applications make. It&#8217;s not actually enforced: you could still force a volume to be unmounted and claiming a disk for exclusive use doesn&#8217;t stop anyone else from using it (like advisory file locks). You can see some of these notifications flying around by using <code>disktool</code> with the undocumented <code>-y</code> flag. You can get more debug by hacking the <code>com.apple.diskarbitration.plist</code> file in <code>/System/Library/LaunchDaemons</code> and adding the <code>-d</code> flag to the argument list. You&#8217;ll then get <code>/var/log/diskarbitrationd.log</code>.</p>

<p><code>diskarbitrationd</code> is the main daemon that&#8217;s responsible for all this stuff. The source code for it and related things can be found on the Open Source part of Apple&#8217;s site. To use Disk Arbitration from within your application, you need to link to the Disk Arbitration framework. It was a private framework in Panther (10.3) but was made public in Tiger (10.4). Things like Spotlight use it to know when to stop indexing a volume when you want to unmount a volume and you should use it too if you&#8217;re writing a similar application.</p>

<p>There are a couple of files that it looks at to tell it what to do. <code>/etc/fstab</code> is one of them. The shipped version (in Leopard) has some examples in the comments of <code>/etc/fstab</code> and the <code>man</code> page looks pretty good. By making the appropriate change to this file, you can, amongst other things, stop a volume from being automatically mounted. The other file it looks at is <code>/var/db/volinfo.database</code>. This text file stores the setting of the &#8220;Ignore ownership of this volume&#8221; flag that you see in Finder.</p>

<p>Disk Arbitration will also give you information about all the disks and volumes on the system. Here&#8217;s the kind of information it might have about your startup volume:</p>

<pre><code>
{
    DAAppearanceTime = 244372661.099552;
    DABusName = PMP;
    DABusPath = "IODeviceTree:/PCI0@0/SATA@1F,2/PRT2@2/PMP@0";
    DADeviceInternal = 1;
    DADeviceModel = "WDC WD1600JS-40NGB2                     ";
    DADevicePath = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleAHCI/PRT2@2/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice";
    DADeviceProtocol = SATA;
    DADeviceRevision = "10.02E04";
    DADeviceUnit = 0;
    DAMediaBSDMajor = 14;
    DAMediaBSDMinor = 3;
    DAMediaBSDName = disk0s3;
    DAMediaBSDUnit = 0;
    DAMediaBlockSize = 512;
    DAMediaContent = "48465300-0000-11AA-AA11-00306543ECAC";
    DAMediaEjectable = 0;
    DAMediaIcon =     {
        CFBundleIdentifier = "com.apple.iokit.IOStorageFamily";
        IOBundleResourceFile = "Internal.icns";
    };
    DAMediaKind = IOMedia;
    DAMediaLeaf = 1;
    DAMediaName = "Macintosh HD";
    DAMediaPath = "IODeviceTree:/PCI0@0/SATA@1F,2/PRT2@2/PMP@0/@0:3";
    DAMediaRemovable = 0;
    DAMediaSize = 138155196416;
    DAMediaUUID = &lt;NSCFType: 0xd32f150&gt;;
    DAMediaWhole = 0;
    DAMediaWritable = 1;
    DAVolumeKind = hfs;
    DAVolumeMountable = 1;
    DAVolumeName = "Macintosh HD";
    DAVolumeNetwork = 0;
    DAVolumePath = file://localhost/;
    DAVolumeUUID = &lt;NSCFType: 0xd3316b0&gt;;
}
</code></pre>

<p>That&#8217;s obviously for a specific partition on a disk. There&#8217;s another entry that represents the whole disk.</p>

<p>Something to note regarding disk/volume UUIDs: GUID partition schemes have a UUID that is used for the partition but in addition to that, there is a UUID that is stored as part of the file system (in the case of HFS+, it&#8217;s not actually a UUID but eight bytes that get turned into a UUID), so if you do end up using them, make sure you know which one you&#8217;re dealing with. The UUID reported by Disk Arbitration happens to be the file system UUID but the UUID property of IOMedia objects is from the partition table.</p>

<p>One thing that isn&#8217;t ideal is there&#8217;s no actual notification indicating when the system wants to eject a disk. You can use the eject approval notification, but then there&#8217;s no way to find out if the eject was ultimately approved. This would be a problem for, say, an indexing application, where it might want to release all resources for the disk (so that the eject will actually succeed) when an eject is requested. Spotlight probably uses the eject approval callback, but the only way it would be able to restart indexing on a volume that failed to eject, is by checking again after a certain amount of time (I don&#8217;t know if it does that).</p>

<p>Another problem I found recently is that bad clients can cause it to eat memory and this in turn can cause kernel memory leaks (of IOMedia objects). For example, on the currently shipping version of Leopard, the WindowServer process doesn&#8217;t appear to be properly processing Disk Arbitration notifications (probably because it uses a funny run loop) which is ultimately causing IOMedia objects to hang around in the kernel. It&#8217;s not a big deal but it does need fixing.</p>

<p>Oh, and one other thing, the system does not like it if Disk Arbitration crashes. Even though <code>launchd</code> will restart it, you still need to reboot as Finder and other processes don&#8217;t connect to the new version.</p>
]]></description>
            <link>http://sutes.co.uk/2008/10/disk-arbitration.html</link>
            <guid>http://sutes.co.uk/2008/10/disk-arbitration.html</guid>
            
            
            <pubDate>Sat, 25 Oct 2008 15:43:00 +1000</pubDate>
        </item>
        
        <item>
            <title>Lock Free Data Structures</title>
            <description><![CDATA[<p>Lock free data structures are interesting I think. It&#8217;s usually much simpler to keep things simple and use regular locks but if you have a need for speed, lock free data structures can give that to you.</p>

<p>I was curious to know what difference it would make for a simple FIFO queue so I knocked up a mostly lock free based implementation and a conventional lock based version.  I chose to make things slightly harder by choosing a fixed size queue and having it block when the queue was full.</p>

<p>The lock free version was nearly thirty times faster on the machine I tested it on. Disclaimer: I did this pretty quickly and I wouldn&#8217;t be surprised if there are bugs (I haven&#8217;t tested it on a multiprocessor weakly ordered architecture machine).</p>

<p>Here&#8217;s the <a href="/stuff/lf-queue.zip">code</a>.</p>
]]></description>
            <link>http://sutes.co.uk/2008/10/lock-free-data-structures.html</link>
            <guid>http://sutes.co.uk/2008/10/lock-free-data-structures.html</guid>
            
            
            <pubDate>Tue, 07 Oct 2008 20:58:42 +1000</pubDate>
        </item>
        
        <item>
            <title>App Store Rejections</title>
            <description><![CDATA[<p>Now that the iPhone NDA has been lifted, all whining is now focused on App Store rejections. I&#8217;m sure you&#8217;ve all just read <a href="http://daringfireball.net/2008/10/the_fear">Gruber&#8217;s post</a>. I&#8217;d just like to throw another theory in: what if Apple is rejecting these applications because they offer features that they are planning to add to their applications. If they allow these third party applications, then a) the fanfare when they announce their equivalent feature isn&#8217;t as good and b) they&#8217;re going to piss people off who&#8217;ve developed the third party application and also those that bought the application. By rejecting these applications early, they&#8217;re doing the developers a favour: better rejected now than find their application obsolete in a few months time. Obviously, it would be better if you could get rejected even earlier as Gruber and <a href="http://speirs.org/2008/10/02/fnda-is-now-former-nda/">others</a> have suggested. </p>
]]></description>
            <link>http://sutes.co.uk/2008/10/app-store-rejections.html</link>
            <guid>http://sutes.co.uk/2008/10/app-store-rejections.html</guid>
            
            
            <pubDate>Fri, 03 Oct 2008 10:13:54 +1000</pubDate>
        </item>
        
        <item>
            <title>iTunes 8 Update</title>
            <description><![CDATA[<p>I&#8217;ve just done the iTunes 8 update along with the QuickTime and other updates listed and found that OS X had a problem starting up afterwards. Anyway, I&#8217;ve tracked down the problem to it being a corrupted <code>/etc/authorization</code> file. Restoring this file fixes the problem. I&#8217;m not 100% sure it wasn&#8217;t something else I was doing that caused this but thought I&#8217;d post in case someone else encounters the problem.</p>

<p>Update: I thought I might explain how I figured out it was the <code>/etc/authorization</code> file was corrupt since you could use the same techniques to debug other start up issues.</p>

<p>The first thing I did was to boot up from another drive and run Disk Utility: no problems. Then I had a look at the <code>system.log</code> file in <code>/var/log/</code>. It showed a bunch of errors but the first one indicated that <code>securityd</code> had crashed. The crash log (stored in <code>/Library/Logs/CrashReporter/</code>) showed a crash in <code>CFDictionaryContainsKey</code> which got me thinking it was a problem with a property list file somewhere. To figure out which property list file, I booted the system in single user mode (Command-S) and typed:</p>

<pre><code>    mount -uw /
    fs_usage &gt;/var/log/fs-usage &amp;
</code></pre>

<p>and then:</p>

<pre><code>    exit
</code></pre>

<p>to continue booting. After rebooting into a working system, I was able to examine the <code>/var/log/fs-usage</code> file. I looked for the last thing that <code>securityd</code> did before it crashed and that was to read <code>/etc/authorization</code> and sure enough the file was garbage when I looked at it.</p>
]]></description>
            <link>http://sutes.co.uk/2008/09/itunes-8-update.html</link>
            <guid>http://sutes.co.uk/2008/09/itunes-8-update.html</guid>
            
            
            <pubDate>Wed, 10 Sep 2008 17:35:54 +1000</pubDate>
        </item>
        
        <item>
            <title>Table Views with Variable Row Heights</title>
            <description><![CDATA[<p><code>NSTableView</code> allows you to have variable row heights in Leopard but <a href="/stuff/CSDynamicRowTableView.zip">here&#8217;s some code</a> (MIT license) that will work back to 10.3. It works around a few awkward issues in Tiger and earlier that I suspect are fixed in Leopard. </p>
]]></description>
            <link>http://sutes.co.uk/2008/09/table-views-with-variable-row.html</link>
            <guid>http://sutes.co.uk/2008/09/table-views-with-variable-row.html</guid>
            
            
            <pubDate>Wed, 03 Sep 2008 13:07:16 +1000</pubDate>
        </item>
        
    </channel>
</rss>
