I've read the article about scope guards (Generic: Change the Way You Write Exception-Safe Code — Forever) in DDJ and I understand their common use.
However, the common use is to instantiate a particular stack guard on the stack for a particular operation, e.g.:
{
FILE* topSecret = fopen("cia.txt");
ON_BLOCK_EXIT(std::fclose, topSecret);
... use topSecret ...
} // topSecret automagically closed
but what if I want to schedule cleanup operations in runtime, e.g. when I have a loop:
{
vector<FILE*> topSecretFiles;
for (int i=0; i<numberOfFiles; ++i)
{
char filename[256];
sprintf(filename, "cia%d.txt", i);
FILE* topSecret = fopen(filename);
topSecretFiles.push_back(topSecret);
ON_BLOCK_EXIT(std::fclose, topSecret); // no good
}
}
Obviously, the above example wouldn't work, since topSecret would be closed along with the for scope. I'd like a scope guard pattern where I can just as easily queue up cleanup operations which I determine to be needed at runtime. Is there something like this available?
I can't push scope guard objects into a standard queue, cause the original object (the one I'm pushing) would be dismissed in the process. How about pushing heap-allocated stack guards and using a queue which deletes its members on dtor? Does anyone have a more clever approach?
It seems you don't appreciate RAII for what it is. These scope guards are nice on occasion for local ("scope") things but you should try to avoid them in favour of what RAII is really supposed to do: encapsulating a resource in an object. The type FILE* is really just not good at that.
Here's an alternative:
void foo() {
typedef std::tr1::shared_ptr<FILE> file_sptr;
vector<file_sptr> bar;
for (...) {
file_sptr fsp ( std::fopen(...), std::fclose );
bar.push_back(fsp);
}
}
Or:
void foo() {
typedef std::tr1::shared_ptr<std::fstream> stream_sptr;
vector<stream_sptr> bar;
for (...) {
file_sptr fsp ( new std::fstream(...) );
bar.push_back(fsp);
}
}
Or in "C++0x" (upcoming C++ standard):
void foo() {
vector<std::fstream> bar;
for (...) {
// streams will become "movable"
bar.push_back( std::fstream(...) );
}
}
Edit: Since I like movable types in C++0x so much and you showed interest in it: Here's how you could use unique_ptr in combination with FILE* without any ref-counting overhead:
struct file_closer {
void operator()(FILE* f) const { if (f) std::fclose(f); }
};
typedef std::unique_ptr<FILE,file_closer> file_handle;
file_handle source() {
file_handle fh ( std::fopen(...) );
return fh;
}
int sink(file_handle fh) {
return std::fgetc( fh.get() );
}
int main() {
return sink( source() );
}
(untested)
Be sure to check out Dave's blog on efficient movable value types
Huh, turns out the DDJ scope guard is "movable", not in the C++0x sense, but in the same sense that an auto_ptr is movable: during the copy ctor, the new guard "dismisses" the old guard (like auto_ptr's copy ctor calls the old one's auto_ptr::release).
So I can simply keep a queue<ScopeGuard> and it'll work:
queue<ScopeGuard> scopeGuards;
// ...
for (...)
{
// the temporary scopeguard is being neutralized when copied into the queue,
// so it won't cause a double call of cleanupFunc
scopeGuards.push_back(MakeScopeGuard(cleanupFunc, arg1));
// ...
}
By the way, thank you for the answer above. It was informative and educational to me in different ways.
Related
I have a function which I would like to have the strong exception guarantee:
class X {
/* Fields and stuff */
void some_function() {
vector1.push_back(/*...*/); // May Throw
vector2.push_back(/*...*/); // May Throw
vector3.push_back(/*...*/); // May Throw
vector4.push_back(/*...*/); // May Throw
}
};
The only way I can think of making this having the strong exception guarantee is the following:
class X {
/* Fields and stuff */
void some_function() {
try { vector1.push_back(/*...*/);};
catch (Vector1PushBackException) {
throw Vector1PushBackException;
}
try { vector2.push_back(/*...*/);};
catch (Vector2PushBackException) {
vector1.pop_back();
throw Vector2PushBackException;
}
try { vector3.push_back(/*...*/);};
catch (Vector3PushBackException) {
vector1.pop_back();
vector2.pop_back();
throw Vector3PushBackException;
}
try { vector4.push_back(/*...*/);};
catch (Vector4PushBackException) {
vector1.pop_back();
vector2.pop_back();
vector3.pop_back();
throw Vector4PushBackException;
}
}
};
However, this is really ugly and error-prone!! Is there a better solution than the one I put above? I can hear someone telling me that I need to use RAII, but I can't figure it out how, since the pop_back operations must not be done when the function returns normally.
I would also like any solution to be zero - overhead on the happy path; I really need the happy path to be as fast as possible.
The solution is to use scope guards.
See this answer for an example implementation of them; I'm not going to repeat it here. With scope guards, your code will look like this:
vector1.push_back(/*...*/);
FINALLY_ON_THROW( vector1.pop_back(); )
vector2.push_back(/*...*/);
FINALLY_ON_THROW( vector2.pop_back(); )
vector3.push_back(/*...*/);
FINALLY_ON_THROW( vector3.pop_back(); )
vector4.push_back(/*...*/);
FINALLY_ON_THROW( vector4.pop_back(); )
Here, FINALLY_ON_THROW is a macro (see link above). Rather than executing it's parameter immediately, it causes it to be executed when you leave the current scope because of an exception. If you instead leave the scope the normal way, the parameter is ignored. If you leave the scope before control reaches the guard in the first place, it's also ignored.
Note that the last guard is superfluous if nothing after it (in the same scope) can throw.
A problem with simply popping back is that it won't necessarily restore the vector to the original state. If adding the element caused any of the vectors to reallocate, then iterators / references to the elements would be invalidated and that invalidation cannot be rolled back making strong exception guarantee impossible.
A safe and simple and general solution is to make the modifications on a copy. Copying of course has an extra cost though.
void some_function() {
auto copy = *this;
copy.vector1.push_back(/*...*/); // May Throw
copy.vector2.push_back(/*...*/); // May Throw
copy.vector3.push_back(/*...*/); // May Throw
copy.vector4.push_back(/*...*/); // May Throw
*this = std::move(copy);
}
HolyBlackCat's scope guard suggestion is an elegant solution in cases where rollback is possible such as if you used another container that doesn't invalidate iterators / references, or if you simply don't care about the invalidation or if you have a class invariant that prevents the function from being called when the capacity is full.
You could feasibly, and at marginal extra cost, first check whether all vectors have extra capacity and choose between copying and rollback based on the check. This allows the caller to not pay the cost of copying if they reserve sufficient capacity beforehand. That does stray further from elegance however.
You can do it in many ways... For example like this:
#include <vector>
#include <type_traits>
#include <exception>
template<class F>
struct on_fail
{
F f_;
int count_{ std::uncaught_exceptions() };
~on_fail()
{
// C++20 is here and still no easy way to tell "unwinding" and "leaving scope" apart
if (std::uncaught_exceptions() > count_) f_();
}
};
template<class F> on_fail(F) -> on_fail<F>;
auto emplace_back_x(auto& v, auto&& x)
{
v.emplace_back(std::forward<decltype(x)>(x));
return on_fail{[&v]{ v.pop_back(); }};
}
int bar();
template<class F>
struct inplacer
{
F f_;
operator std::invoke_result_t<F&>() { return f_(); }
};
template<class F> inplacer(F) -> inplacer<F>;
void foo()
{
std::vector<int> v1, v2, v3;
auto rollback1 = emplace_back_x(v1, 1);
auto rollback2 = emplace_back_x(v2, inplacer{ bar });
auto rollback3 = emplace_back_x(v3, inplacer{ []{ return bar() + 1; } });
}
Note that your example is not correct: if push_back() fails with std::bad_alloc (or any other exception) -- you fail to perform undo step.
Also, perhaps in your case it make sense to use basic guarantee? In practice you can often deal with it on a higher level -- e.g. disconnect and discard entire accumulated state, leaving client to reconnect and repeat attempt.
How about this?
class X {
/* Fields and stuff */
void some_function() {
vector1.push_back(/*...*/); // May Throw
try {
vector2.push_back(/*...*/); // May Throw
try {
vector3.push_back(/*...*/); // May Throw
try {
vector4.push_back(/*...*/); // May Throw
} catch(...) {
vector3.pop_back();
throw;
}
} catch(...) {
vector2.pop_back();
throw;
}
} catch(...) {
vector1.pop_back();
throw;
}
}
};
But... do you really need 4 different vectors?
class X {
/* Fields and stuff */
void some_function() {
vector1234.push_back(std::make_tuple(/*...*/, /*...*/, /*...*/, /*...*/)); // May Throw
}
};
I have the following code:
class ClassA
{
public:
ClassA(std::string str);
std::string GetSomething();
};
int main()
{
std::string s = "";
try
{
ClassA a = ClassA(s);
}
catch(...)
{
//Do something
exit(1);
}
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
I would like the last line could access the a variable. How could I achieve that, given ClassA doesn't have default constructor ClassA() and I would not like to use pointers? Is the only way to add a default constructor to ClassA?
You can't or shouldn't. Instead you could just use it within the try block, something like:
try
{
ClassA a = ClassA(s);
std::string result = a.GetSomething();
}
catch(...)
{
//Do something
exit(1);
}
The reason is that since a goes out of scope after the try block referring to the object after that is undefined behavior (if you have a pointer to where it were).
If you're concerned with a.GetSomething or the assignment throws you could put a try-catch around that:
try
{
ClassA a = ClassA(s);
try {
std::string result = a.GetSomething();
}
catch(...) {
// handle exceptions not from the constructor
}
}
catch(...)
{
//Do something only for exception from the constructor
exit(1);
}
You can use some sort of optional or just use std::unique_ptr.
int main()
{
std::string s = "";
std::unique_ptr<ClassA> pa;
try
{
pa.reset(new ClassA(s));
}
catch
{
//Do something
exit(1);
}
ClassA& a = *pa; // safe because of the exit(1) in catch() block
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
Of course, just extending the try block to include the usage of a is the simplest solution.
Also, if you were really planning to exit(1) or otherwise abort the program on failure then simply don't put a try block here at all. The exception will propagate up, aborting the program if it is not caught .
One alternative is to use std::optional . This is the same sort of concept as using a pointer, but it uses automatic allocation and so you are less likely to create a memory leak. This is currently experimental status; you can use boost::optional instead if your compiler doesn't have std::experimental::optional:
#include <experimental/optional>
using std::experimental::optional;
using std::experimental::in_place;
// ...
optional<ClassA> a;
try
{
a = optional<ClassA>(in_place, s);
}
catch(...)
{
// display message or something
}
std::string result;
if ( a )
result = a->GetSomething();
I'd like to reiterate though that this is a bit of a spaghetti style and it'd be better to design your code differently so you aren't continually testing whether construction succeeded or failed.
This requires ClassA be movable or copyable. The in_place is a special argument which invokes a perfect forwarding constructor for the remaining arguments. Without in_place you can only give an actual ClassA as constructor argument, it doesn't consider implicit conversions to ClassA. (This is how optional avoids the ambiguity between copy-construction and list-initialization from object of the same type).
Here is my issue.
I have a class to create timed events. It takes in:
A function pointer of void (*func)(void* arg)
A void* to the argument
A delay
The issue is I may want to create on-the-fly variables that I dont want to be a static variable in the class, or a global variable. If either of these are not met, I cant do something like:
void doStuff(void *arg)
{
somebool = *(bool*)arg;
}
void makeIt()
{
bool a = true;
container->createTimedEvent(doStuff,(void*)&a,5);
}
That wont work because the bool gets destroyed when the function returns. So I'd have to allocate these on the heap. The issue then becomes, who allocates and who deletes. what I'd like to do is to be able to take in anything, then copy its memory and manage it in the timed event class. But I dont think I can do memcpy since I dont know the tyoe.
What would be a good way to acheive this where the time event is responsible for memory managment.
Thanks
I do not use boost
class AguiTimedEvent {
void (*onEvent)(void* arg);
void* argument;
AguiWidgetBase* caller;
double timeStamp;
public:
void call() const;
bool expired() const;
AguiWidgetBase* getCaller() const;
AguiTimedEvent();
AguiTimedEvent(void(*Timefunc)(void* arg),void* arg, double timeSec, AguiWidgetBase* caller);
};
void AguiWidgetContainer::handleTimedEvents()
{
for(std::vector<AguiTimedEvent>::iterator it = timedEvents.begin(); it != timedEvents.end();)
{
if(it->expired())
{
it->call();
it = timedEvents.erase(it);
}
else
it++;
}
}
void AguiWidgetBase::createTimedEvent( void (*func)(void* data),void* data,double timeInSec )
{
if(!getWidgetContainer())
return;
getWidgetContainer()->addTimedEvent(AguiTimedEvent(func,data,timeInSec,this));
}
void AguiWidgetContainer::addTimedEvent( const AguiTimedEvent &timedEvent )
{
timedEvents.push_back(timedEvent);
}
Why would you not use boost::shared_ptr?
It offers storage duration you require since an underlying object will be destructed only when all shared_ptrs pointing to it will have been destructed.
Also it offers full thread safety.
Using C++0x unique_ptr is perfect for the job. This is a future standard, but unique_ptr is already supported under G++ and Visual Studio. For C++98 (current standard), auto_ptr works like a harder to use version of unique_ptr... For C++ TR1 (implemented in Visual Studio and G++), you can use std::tr1::shared_ptr.
Basically, you need a smart pointer. Here's how unique_ptr would work:
unique_ptr<bool> makeIt(){ // More commonly, called a "source"
bool a = true;
container->createTimedEvent(doStuff,(void*)&a,5);
return new unique_ptr<bool>(a)
}
When you use the code later...
void someFunction(){
unique_ptr<bool> stuff = makeIt();
} // stuff is deleted here, because unique_ptr deletes
// things when they leave their scope
You can also use it as a function "sink"
void sink(unique_ptr<bool> ptr){
// Use the pointer somehow
}
void somewhereElse(){
unique_ptr<bool> stuff = makeIt();
sink(stuff);
// stuff is now deleted! Stuff points to null now
}
Aside from that, you can use unique_ptr like a normal pointer, aside from the strange movement rules. There are many smart pointers, unique_ptr is just one of them. shared_ptr is implemented in both Visual Studio and G++ and is the more typical ptr. I personally like to use unique_ptr as often as possible however.
If you can't use boost or tr1, then what I'd do is write my own function that behaves like auto_ptr. In fact that's what I've done on a project here that doesn't have any boost or tr1 access. When all of the events who care about the data are done with it it automatically gets deleted.
You can just change your function definition to take in an extra parameter that represents the size of the object passed in. Then just pass the size down. So your new function declarations looks like this:
void (*func)(void* arg, size_t size)
void doStuff(void *arg, size_t size)
{
somebool = *(bool*)arg;
memcpy( arg, myStorage, size );
}
void makeIt()
{
bool a = true;
container->createTimedEvent(doStuff,(void*)&a,sizeof(bool), 5);
}
Then you can pass variables that are still on the stack and memcpy them in the timed event class. The only problem is that you don't know the type any more... but that's what happens when you cast to void*
Hope that helps.
You should re-work your class to use inheritance, not a function pointer.
class AguiEvent {
virtual void Call() = 0;
virtual ~AguiEvent() {}
};
class AguiTimedEvent {
std::auto_ptr<AguiEvent> event;
double timeSec;
AguiWidgetBase* caller;
public:
AguiTimedEvent(std::auto_ptr<AguiEvent> ev, double time, AguiWidgetBase* base)
: event(ev)
, timeSec(time)
, caller(base) {}
void call() { event->Call(); }
// All the rest of it
};
void MakeIt() {
class someclass : AguiEvent {
bool MahBool;
public:
someclass() { MahBool = false; }
void Call() {
// access to MahBool through this.
}
};
something->somefunc(AguiTimedEvent(new someclass())); // problem solved
}
I was commenting on an answer that thread-local storage is nice and recalled another informative discussion about exceptions where I supposed
The only special thing about the
execution environment within the throw
block is that the exception object is
referenced by rethrow.
Putting two and two together, wouldn't executing an entire thread inside a function-catch-block of its main function imbue it with thread-local storage?
It seems to work fine, albeit slowly. Is this novel or well-characterized? Is there another way of solving the problem? Was my initial premise correct? What kind of overhead does get_thread incur on your platform? What's the potential for optimization?
#include <iostream>
#include <pthread.h>
using namespace std;
struct thlocal {
string name;
thlocal( string const &n ) : name(n) {}
};
struct thread_exception_base {
thlocal &th;
thread_exception_base( thlocal &in_th ) : th( in_th ) {}
thread_exception_base( thread_exception_base const &in ) : th( in.th ) {}
};
thlocal &get_thread() throw() {
try {
throw;
} catch( thread_exception_base &local ) {
return local.th;
}
}
void print_thread() {
cerr << get_thread().name << endl;
}
void *kid( void *local_v ) try {
thlocal &local = * static_cast< thlocal * >( local_v );
throw thread_exception_base( local );
} catch( thread_exception_base & ) {
print_thread();
return NULL;
}
int main() {
thlocal local( "main" );
try {
throw thread_exception_base( local );
} catch( thread_exception_base & ) {
print_thread();
pthread_t th;
thlocal kid_local( "kid" );
pthread_create( &th, NULL, &kid, &kid_local );
pthread_join( th, NULL );
print_thread();
}
return 0;
}
This does require defining new exception classes derived from thread_exception_base, initializing the base with get_thread(), but altogether this doesn't feel like an unproductive insomnia-ridden Sunday morning…
EDIT: Looks like GCC makes three calls to pthread_getspecific in get_thread. EDIT: and a lot of nasty introspection into the stack, environment, and executable format to find the catch block I missed on the first walkthrough. This looks highly platform-dependent, as GCC is calling some libunwind from the OS. Overhead on the order of 4000 cycles. I suppose it also has to traverse the class hierarchy but that can be kept under control.
In the playful spirit of the question, I offer this horrifying nightmare creation:
class tls
{
void push(void *ptr)
{
// allocate a string to store the hex ptr
// and the hex of its own address
char *str = new char[100];
sprintf(str, " |%x|%x", ptr, str);
strtok(str, "|");
}
template <class Ptr>
Ptr *next()
{
// retrieve the next pointer token
return reinterpret_cast<Ptr *>(strtoul(strtok(0, "|"), 0, 16));
}
void *pop()
{
// retrieve (and forget) a previously stored pointer
void *ptr = next<void>();
delete[] next<char>();
return ptr;
}
// private constructor/destructor
tls() { push(0); }
~tls() { pop(); }
public:
static tls &singleton()
{
static tls i;
return i;
}
void *set(void *ptr)
{
void *old = pop();
push(ptr);
return old;
}
void *get()
{
// forget and restore on each access
void *ptr = pop();
push(ptr);
return ptr;
}
};
Taking advantage of the fact that according to the C++ standard, strtok stashes its first argument so that subsequent calls can pass 0 to retrieve further tokens from the same string, so therefore in a thread-aware implementation it must be using TLS.
example *e = new example;
tls::singleton().set(e);
example *e2 = reinterpret_cast<example *>(tls::singleton().get());
So as long as strtok is not used in the intended way anywhere else in the program, we have another spare TLS slot.
I think you're onto something here. This might even be a portable way to get data into callbacks that don't accept a user "state" variable, as you've mentioned, even apart from any explicit use of threads.
So it sounds like you've answered the question in your subject: YES.
void *kid( void *local_v ) try {
thlocal &local = * static_cast< thlocal * >( local_v );
throw local;
} catch( thlocal & ) {
print_thread();
return NULL;
}
==
void *kid (void *local_v ) { print_thread(local_v); }
I might be missing something here, but it's not a thread local storage, just unnecessarily complicated argument passing. Argument is different for each thread only because it is passed to pthread_create, not because of any exception juggling.
It turned out that I indeed was missing that GCC is producing actual thread local storage calls in this example. It actually makes the issue interesting. I'm still not quite sure whether it is a case for other compilers, and how is it different from calling thread storage directly.
I still stand by my general argument that the same data can be accessed in a more simple and straight-forward way, be it arguments, stack walking or thread local storage.
Accessing data on the current function call stack is always thread safe. That's why your code is thread safe, not because of the clever use of exceptions. Thread local storage allows us to store per-thread data and reference it outside of the immediate call stack.
I just got burned by a bug that is partially due to my lack of understanding, and partially due to what I think is suboptimal design in our codebase. I'm curious as to how my 5-minute solution can be improved.
We're using ref-counted objects, where we have AddRef() and Release() on objects of these classes. One particular object is derived from the ref-count object, but a common function to get an instance of these objects (GetExisting) hides an AddRef() within itself without advertising that it is doing so. This necessitates doing a Release at the end of the functional block to free the hidden ref, but a developer who didn't inspect the implementation of GetExisting() wouldn't know that, and someone who forgets to add a Release at the end of the function (say, during a mad dash of bug-fixing crunch time) leaks objects. This, of course, was my burn.
void SomeFunction(ProgramStateInfo *P)
{
ThreadClass *thread = ThreadClass::GetExisting( P );
// some code goes here
bool result = UseThreadSomehow(thread);
// some code goes here
thread->Release(); // Need to do this because GetExisting() calls AddRef()
}
So I wrote up a little class to avoid the need for the Release() at the end of these functions.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * Thread() const { return m_T; }
};
So that now I can just do this:
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC.Thread());
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}
What I don't like is that to access the thread pointer, I have to call a member function of ThreadContainer, Thread(). Is there some clever way that I can clean that up so that it's syntactically prettier, or would anything like that obscure the meaning of the container and introduce new problems for developers unfamiliar with the code?
Thanks.
use boost::shared_ptr
it is possible to define your own destructor function, such us in next example: http://www.boost.org/doc/libs/1_38_0/libs/smart_ptr/sp_techniques.html#com
Yes, you can implement operator ->() for the class, which will recursively call operator ->() on whatever you return:
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * operator -> () const { return m_T; }
};
It's effectively using smart pointer semantics for your wrapper class:
Thread *t = new Thread();
...
ThreadContainer tc(t);
...
tc->SomeThreadFunction(); // invokes tc->t->SomeThreadFunction() behind the scenes...
You could also write a conversion function to enable your UseThreadSomehow(ThreadContainer tc) type calls in a similar way.
If Boost is an option, I think you can set up a shared_ptr to act as a smart reference as well.
Take a look at ScopeGuard. It allows syntax like this (shamelessly stolen from that link):
{
FILE* topSecret = fopen("cia.txt");
ON_BLOCK_EXIT(std::fclose, topSecret);
... use topSecret ...
} // topSecret automagically closed
Or you could try Boost::ScopeExit:
void World::addPerson(Person const& aPerson) {
bool commit = false;
m_persons.push_back(aPerson); // (1) direct action
BOOST_SCOPE_EXIT( (&commit)(&m_persons) )
{
if(!commit)
m_persons.pop_back(); // (2) rollback action
} BOOST_SCOPE_EXIT_END
// ... // (3) other operations
commit = true; // (4) turn all rollback actions into no-op
}
I would recommend following bb advice and using boost::shared_ptr<>. If boost is not an option, you can take a look at std::auto_ptr<>, which is simple and probably addresses most of your needs. Take into consideration that the std::auto_ptr has special move semantics that you probably don't want to mimic.
The approach is providing both the * and -> operators together with a getter (for the raw pointer) and a release operation in case you want to release control of the inner object.
You can add an automatic type-cast operator to return your raw pointer. This approach is used by Microsoft's CString class to give easy access to the underlying character buffer, and I've always found it handy. There might be some unpleasant surprises to be discovered with this method, as in any time you have an implicit conversion, but I haven't run across any.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
operator ThreadClass *() const { return m_T; }
};
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC);
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}