[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    KDE and Threading
From:       Bavo De Ridder <bavo () ace ! ulyssis ! student ! kuleuven ! ac ! be>
Date:       1998-11-30 11:34:13
[Download RAW message or body]

Hello,

As you all know, X and multithreading is not the perfect team. Although the
XLib functions have been made threadsafe, the use of the connectionchannel is
still prone to race conditions. For this reason one has to make sure every UI
call should be made on one single thread.

In C++ you can't specifie which thread a function should use. One possible
solution would be to pass a pointer to a fully curried method to a threadqueue.
This queue will then later on call the fully curried method (it won't need
parameters since the method is curried.)

But now you will ask: Currying in C++, that is not possible. Wel it is. I have
written a partial solution for currying a method. Of that code works, we can
savely call any UI code, regardless on which thread we are. The goal is the
following:

in myfunction()
{
	new UICall3<Object, P1, P2, P3>(o,methodpointer)
		->cury(p1,p2,p3)->callBlocking(); 
	...
}

The code is as follows:

class UICall
{
public:
	virtual void operator() = 0; 
	virtual void signalCalled() 
	{
		use POSIX signals to signal the succesfull call
	}
	virtual void waitCalled()
	{
		wait on the above signal.
	}
};

// for currying 3 parameters.
template<class O, class P1, class P2, class P3>
class UICall3 : public UICall
{
public:
	UICall3(O &o)
	{
		// Save the object reference
	}

	UICall3 &curry(P1 p1, P2 p2, P3 p3)
	{
		// Save the parameters
	}

	UICall3 &callBlocking
	{
		// queue (UICall *)this and wait.
	}

	void operator () ()
	{
		call the method with the saved parameters.
	}
};

The above code should work. Although it seems very simple, it's use is very
complicated. First off all: semaphores should be used instead of signals. It is
always possible the UICall is signalled before it is waiting for the signal:
deadlock. Secondly both a synchrone as an asynchrone call should be provided.
Use the synchrone one when passing locally allocated variables. 

Advantages:

	- You can choose on which thread a function gets executed.
	- You can execute asynchroon or synchroon.

Disadvantages:

	- Complicated use: only for experienced users
	- return values through reference parameters.
	- exceptions are directly possible (I have a very rudimentary
	  idea for passing exceptions).

Perhaps a lot of the disadvantages could be eliminated by the use of a few
assembler functions. The guys of kaffe have a lot of expertise on C++ function
calls in assembler.

Any comments on the above?


BDR

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic