Luke Dalessandro wrote:
>
>
> Greg wrote:
>
>> Luke Dalessandro wrote:
>>
>>> Code: Thread -> U
>>> -> T
>>>
>>> public class Thread {
>>> protected:
>>> thread_t _tid;
>>> virtual void foo() = 0;
>>>
>>> public:
>>> // Static entry function for the internal thread
>>> static void* ThreadEntry(void* pThread) {
>>> Thread* thread = static_cast<Thread*>(pThread);
>>>
>>> // ***
>>> // *** This is the error, calls the pure virtual version...?
>>> // ***
>>> thread->foo();
>>> return 0;
>>> }
>>>
>>> // Starts the internal thread running
>>> void Start() {
>>> pthread_create(&_tid, NULL, Thread::ThreadEntry, this);
>>> }
>>> }
>>>
>>> public class T : public Thread {
>>> protected:
>>> virtual void foo() {
>>> cout << "I'm a T";
>>> }
>>> }
>>>
>>> public class U : public Thread {
>>> protected:
>>> virtual void foo() {
>>> cout << "I'm a U";
>>> }
>>> }
>>
>>
>>
>>
>>> As you can see I'm just trying to re-use some pthread code for a
>>> multithreaded server that spawns new threads for different reasons. I
>>> can't figure out how to cast the void* to a base Thread* pointer and
>>> call the pure virtual "foo" function and get the derived behavior...
>>>
>>> Of course, the standard usage like
>>>
>>> Thread* u = new U();
>>> u->foo();
>>>
>>> calls the derived foo like I expect.
>>>
>>> I also tried a non-pure virtual foo and the Thread::foo is still getting
>>> called after the cast.
>>>
>>> I'm on OSX 10.4 development version. Not sure which gcc it is.
>>>
>>> Thanks in advance,
>>> Luke
>>
>>
>>
>> The code that allocates the Thread object for each pthread created is
>> missing from your post. In fact there is no obvious execution order to
>> the code that was posted.
>>
>> Without knowing what pThread is actually pointing to, it's not possible
>> to fully diagnose the problem. It's also possible that there is no code
>> in the program to create new Thread objects, in which case the same
>> pThread pointer is being passed to every pthread.
>>
>> Greg
>>
>
> Greg,
>
> Sorry about the lack, I was trying to remove everything that didn't seem
> necessary. The code is basically:
>
> int main (int argc, const * char argv[]) {
>
> string toExit;
> Thread* t;
>
> while (toExit != "exit") {
>
> cin >> toExit;
>
> if (toExit = "U") {
> t = new U();
> }
> else {
> t = new V();
> }
>
> t->Start();
>
> delete t;
>
> }
>
> }
>
> Constructors are:
>
> Thread::Thread() {}
> U::U() {}
> V::V() {}
>
> Destructors are:
>
> virtual ~Thread() {}
> virtual ~U() {}
> virtual ~V() {}
>
> I realize that the main thread s pulling the rug out from under the
> pthreads that are running inside the Thread objects... I'm actually
> storing the pointers somewhere and joining and deleting threads elsewhere.
>
> Luke
Sigh...
I think I solved my own problem. I really was deleting the Thread object
while it's internal thread was still running. This was causing the "pure
virtual function call" because "this" (passed as a void*) had actually
been deleted, so casting it to a Thread didn't cast it to a U or a V.
If I'm more careful about the delete call, ie joining first or
something, it works fine. Multithreading gets me again...
Sorry to bother everyone.
Luke
|