Termination Condition

July 31st, 2007

terminationcondition.gif

Playing with paint: girl with red hair

July 20th, 2007

Another red haired girl. Sticking to same style/colours etc as previously. Think this might end up being a series of very similar paintings, which hopefully will let me slowly improve my technique with each one.

girlredhair.jpg

chrss update 15

July 12th, 2007

More additions to chrss:

  • displaying English tool-tips/hover-overs for moves
  • confirmation of move now describes the move to be made in English
  • number of games that it is your turn to move now displayed when logged in
  • “diagram” link to chessup.net for current game board (as well as when browsing previous moves)

Note chrss will be moving from http://psyhicorigami.com/chrss/ to http://chrss.co.uk/ in the coming weeks. Currently both URLs will work and share the same database, so you are free to use either one. At some point next month I shall most likely set up a permanent redirect from http://psyhicorigami.com/chrss/ to http://chrss.co.uk/, so hopefully the transition will be fairly seamless.

More ctypes callback fun (on Windows this time)

July 7th, 2007

For the same project that I’m using ctypes on OS X I’m also working on a Windows version – again using ctypes for the native interfacing.

In both cases the OS X and Windows specific code does not amount to much (a few hundred lines each, with plenty of spacing). Doing the Windows code was easier in some respects, as I knew what I was trying to achieve. Though not being much of a Windows programmer it was harder in some ways too.

Anyway, just thought I’d share another bug I ran into when working on the Windows code. It’s pretty similar to the garbage collected callback problem I had before, but subtly different:


        overlap_completion=LPOVERLAPPED_COMPLETION_ROUTINE(completion_callback)
        
        # do async reads until the thread stops
        while self._running and self.is_open():
            result=ReadFileEx(self._device_handle,report_buffer,len(report_buffer),byref(overlapped),overlap_completion)
            if not result:
                raise RuntimeError("ReadFileEx failed")
            Kernel32.SleepEx(100,1)

Kernel32 is a ctypes object for kernel32.dll and ReadFileEx is a method from that object, that has had it’s prototypes etc specified in prior code.

The above code (with a lot of the context removed) basically performs overlapping reads on a separate thread. This is so I can receive data from a device, at the same time as writing to the device. If the IO is not done in an overlapping style (e.g. using ReadFile instead of ReadFileEx and not specifying FILE_FLAG_OVERLAPPED when opening the file using CreateFile) the read and write calls would become serialised and only one can happen at a time – even if the are running on separate threads.

Anyway, that code worked fine for some basic tests. I was able to read fine and my callback (completion_callback defined elsewhere) was getting called. However when I ran my unit tests to give the code a good work out I would (usually) end up with either Python freezing, a MemoryError being raised or else a straight crash with Windows prompting me to send a bug report. Hmmm. That’s pretty familiar.

So I checked my code to make sure I wasn’t doing anything wrong (not keeping hold of references to objects etc), but as far as I could tell it was all ok. Quite a few tweaks and partial rewrites ensued. Again I was happy that I could just issue a svn revert to get back to where I’d been.

Then I had a brief thought. My unit tests were constantly opening and closing the device and starting and stopping the thread running that code, but all from within the same process. So each time they were running they weren’t necessarily starting from scratch each time. So ReadFileEx may well have been called before, with a now garbage collected callback. If Windows was then trying to call the callback that was garbage collected that would show the symptoms I was seeing.

A bit more thought and it occurred that I just need to stop the callback ever being called again, as the thread finished. So I simply added:


        Kernel32.CancelIo(self._device_handle)

After the While loop to make sure that any pending IO request were cancelled (for the current thread), thus ensuring my callback would not be called again – prior to it getting garbage collected.

chrss update 14

July 2nd, 2007

Well it turns out that NetNewsWire‘s javascript confirm() function doesn’t actually show a dialog. Instead it just returns false. So if you browsed from the feed to a game and tried to press the resign button not much would happen, as the javascript would behave as if you’d hit the cancel button.

Anyway, changed it to not use javascript for confirmation and instead require you to check a checkbox next to the resign button. That should be sufficient to avoid accidentally clicking on the resign button.