Re: How to rollback another stack in C++?
chengpu@gmail.com wrote:
James Kanze wrote:
[...]
If I could (1) set a catch before calling <IThread>::ProcMsg(); (2)
throw an exception from another thread to the thread calling
<IThread>::ProcMsg(), then I can roll back the stack elegantly to
before <IThread>::ProcMsg().
What you are asking for is the possibility of triggering an
exception asynchronously. In practice, support for this cannot
readily be implemented on all platforms: there are typically
moments when entering or leaving a function when the stack frame
is not fully set up, which makes walking back the stack
impossible.
More specfically, (1) the <IThread> has a pointer to generic exception
which is defaulted to 0; (2) I can make it pointing to a real exception
from aother stack; (3) the context switch handler will check the
exception pointer of <IThread>, and throw it onto the stack whenever
<IThread> becomes current context; (4) the exception itself contains
the message being processed, so that <IThread>::Rollback() on the
message is called.
Note that you'd also have to do something to interrupt any
system calls in progress as well. Suppose the reason the other
thread doesn't finish is because it is deadlocked waiting for
output from some other process, which is waiting for input from
it.
If you can get into scheduler, of course, you can do a lot of
things. Typically, you can't. If you can force the other
thread to collaborate (say by requiring it to use some classes
that you write from time to time), you can achieve much the same
effect. If the other thread can do anything it pleases,
however, there's not much you can do about it.
The problem is that (1) C/C++ does not have mechanism to rollback
another stack; (2) I do not have access to the context switch handler
on either UNIX or Win32; (3) the assemble instruction to pop stack
pointer is in kernel mode so that I can not even write my own version
of stack rolling back.
I'm not sure I understand point (3). You throw an exception in
user mode, and the stack is cleaned up without ever entering
kernel mode. There's no problem rolling back the stack. The
problem is triggering the other thread to stop. (If you roll
back the stack while the other thread is still using it, you're
going to have very big problems.) It might also be a problem
finding out where the top of the stack is for the other thread.
I'm not sure what your application is: perhaps the best solution
is to use a separate process (instead of a thread), possibly
with shared memory. Not that this solves all of your problems
either---systems like Unix may clean up all of the main memory
after process termination, but they still allow secondary memory
(e.g. temporary files) to leak.
Yes. Also process is a big waste for thread execution due to its
overhead, especially in object-to-object communication.
I'm not too familiar with Windows, but depending on how you link
under Solaris, and in general under Linux, the only difference
between different processes and different threads is the way
memory is mapped. If you use shared memory for communication
between the processes, there should be no real difference
between the two.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]