Friday, August 28, 2009

How many outputs in a node, one or more?

That matters.

Tuesday, August 18, 2009

Living Root Bridges

http://rootbridges.blogspot.com/

Fascinated in Qt

I just read some about Qt and soon started fascinated in it. Since the main part of Qt is GUI framework the functionalities Qt offers are roughly the same as wx, if there is on in wx, there's an equivalent in qt (roughly, again). What I am interested is its direct use of C++ methods in a simple and flexible way. wx has event objects, multiple 'bind' types and multiple macros to bind events to callbacks. Qt does it in only two macros, signal, slot, and one method QObject::connect(). It is easy to connect a single event to multiple callbacks, multiple events to a single callback, the programmer doesn't have to be aware of thread, It's so flexible that it can be used in many ways. I looked at Qt WebKit API and found Qt has excellently integrated WebKit, which would have been very difficult if there was no signal-slot mechanism flexibility. Since it doesn't restrict the number and types of arguments of the callbacks, it can be well used for callback type network programming.

I think there's one minor drawback. In wx, what and when wx emits an event is usually explicit in the document. In Qt, the user can easily emits an event so it is not as easy as wx (it's a trade-off). It is also explicit for the events Qt itself emits, but the information is scattered in the document. In wx there's little chance to miss an event type and timing being emit once you get used to reading the document. (if not, read through Event handling overview (Don't miss the difference of event propagation mechanism between command events and other) then 'Events' section of Classes by category. See what kind of events there are in wx, then read the 'Event handling' section of the document of specific window you use, such as wxTextCtrl.)

Saturday, August 1, 2009

Not a nice way to interrupt a sub thread

In my application, the main thread in in charge of UI drawing with wxPython and starting worker threads which runs user defined Python code. If a user defined Python code is buggy the application user needs to stop it. There's a way to raise a KeyboardInterrupt exception in the main thread but unfortunately not the opposite. What I needed to do is interrupting a sub thread from the main thread. I don't know why it doesn't exist. Probably it is a well considered decision but what I need is what Python misses. The API provides a function PyThreadState_SetAsyncExc() which takes a thread id and exception object and raises exception in the thread. So I had to make a wrapper extension.

pySubthreadInterruptTest.c

#include <Python.h>

static PyObject* interrupt(PyObject* self, PyObject* args)
{
    long threadid;
    PyObject* po_exception;
    if(! PyArg_ParseTuple(args, "lO", &threadid, &po_exception))
    {
        return NULL;
    }

    int result = PyThreadState_SetAsyncExc(threadid, po_exception);
    return Py_BuildValue("l", result);
}

static PyMethodDef MethodsDefs[] = {
    {"interrupt", interrupt, METH_VARARGS},
    {NULL, NULL, 0},
};

void initpystit(void){
    (void) Py_InitModule("pystit", MethodsDefs);
}

setup.py
from distutils.core import setup, Extension

module1 = Extension('pystit',
                    sources = ['pySubthreadInterruptTest.c'])

setup (name = 'PackageName',
       version = '1.0',
       description = 'This is a demo package',
       ext_modules = [module1])

test.py
import time, thread
import pystit
def f():
    print 'thread start'
    try:
            for i in range(1000):
                    print i
                    time.sleep(0.001)
    except:
            print 'interrupted'
            raise
    print 'thread end'
tid = thread.start_new_thread(f, ())
time.sleep(0.001)
pystit.interrupt(tid, ValueError)
time.sleep(1)

$ python setup.py build
running build
running build_ext
building 'pystit' extension
gcc -pthread -shared build/temp.linux-i686-2.6/pySubthreadInterruptTest.o -L/usr/lib -lpython2.6 -o build/lib.linux-i686-2.6/pystit.so
$ cd build/lib.linux-i686-2.6/
$ ls
pystit.so  test.py
$ python test.py
thread start
0
1
2
3
interrupted
Unhandled exception in thread started by <function f at 0xb8043e64>
Traceback (most recent call last):
  File "test.py", line 8, in f
    time.sleep(0.001)
ValueError
$ 

It works but I can't say I'm quite satisfied with the solution.