Andrew Stitcher escribió:
On Mon, 2008-06-02 at 18:32 +0200, Manuel Teira wrote:
...
So, I've added some traces to my addFd, delFd, modFd, and wait
implementations, also a log in Dispatcher::run(), showing:
QPID_LOG(trace, "Got an event with handle: " << event.handle
<< " Type: " << typeid(*(event.handle)).name());
Just between the reception of the event, and the downcast attempt.
What I see is::
...
Type: qpid::sys::AsynchIO
Assertion failed: dynamic_cast<Target>(x) == x, file
/opt/dslap/contrib/include/boost/cast.hpp, line 97
Abort (core dumped)
I think you should see a DispatchHandle type not an AsynchIO type (even
if that is the dynamic type), not 100% sure though - this because you do
actually put a DispatchHandle in there (in the Dispatcher code).
That seems to be true, as you can see in the test I'm commenting later.
The problem could be caused by compiling without typeinfo - I don't know
the default settings for the Sun Forte compiler.
I think that RTTI information is on by default. Otherwise, I wouldn't be
able to use typeid and dynamic_cast sentences, would I?
In order to emulate the whole conversion process, I've setup the
following c++ code:
#include <iostream>
#include <assert.h>
using namespace std;
void *ptr;
template <class Target, class Source>
inline Target polymorphic_downcast(Source* x) {
assert(dynamic_cast<Target>(x) == x);
return static_cast<Target>(x);
}
class PollerHandle {
public:
virtual ~PollerHandle() {};
};
class Poller {
public:
void addFd(PollerHandle &handle) {
cout << "In Poller, adding a handle of type: "
<< typeid(handle).name() << endl;
ptr = &handle;
}
};
class DispatchHandle: public PollerHandle {
public:
virtual ~DispatchHandle() {};
void run(Poller &poller) {
cout << "I'm adding myself to the poller as " <<
typeid(this).name() << endl;
poller.addFd(*this);
}
};
class AsynchIO: private DispatchHandle {
public:
void start(Poller &poller) {
DispatchHandle::run(poller);
}
};
class Dispatcher {
public:
void run() {
PollerHandle *handle = static_cast<PollerHandle*>(ptr);
cout << "In Dispatcher::run(), handle is a "
<< typeid(handle).name() << endl;
DispatchHandle *dh = polymorphic_downcast<DispatchHandle*>(handle);
cout << "DispatchHandle is " << dh << " for handle: " << handle << endl;
}
};
int main(int argc, char *argv[]) {
Poller poller;
AsynchIO *aio = new AsynchIO();
aio->start(poller);
Dispatcher dp;
dp.run();
}
Sorry, but I was not able to minimize it further. Anyway, the runtime
result of this program is different using Sun CC and g++. But I'm not
sure about what the problem actually is.
I'm moving into Dispatcher::run() a combination of what is done in the
ECFPoller::wait (static_cast from the event void* user pointer to a
PollerHandle*), and what is done in the Dispatcher::run() method:
downcast it to a DispatchHandle.
The only thing the poller does, is to store the PollerHandle it receives
into the global *ptr void pointer. So, it can be recovered later from
the Dispatcher::run() method.
OK, now , the results:
Solaris 10 . Sun CC Studio 12:
-bash-3.00$ ./typeid
I'm adding myself to the poller as DispatchHandle*
In Poller, adding a handle of type: AsynchIO
In Dispatcher::run(), handle is a PollerHandle*
Assertion failed: dynamic_cast<Target>(x) == x, file typeid.cc, line 10
Abort (core dumped)
Linux 2.6. g++ 4.1.3:
$ ./typeid
I'm adding myself to the poller as P14DispatchHandle
In Poller, adding a handle of type: 8AsynchIO
In Dispatcher::run(), handle is a P12PollerHandle
DispatchHandle is 0x804b008 for handle: 0x804b008
The example works.
Furthermore, if I change the main() to avoid involving the AsyncIO class:
int main(int argc, char *argv[]) {
Poller poller;
DispatchHandle *dh = new DispatchHandle();
dh->run(poller);
Dispatcher dp;
dp.run();
}
The example works now:
I'm adding myself to the poller as DispatchHandle*
In Poller, adding a handle of type: DispatchHandle
In Dispatcher::run(), handle is a PollerHandle*
DispatchHandle is 29160 for handle: 29160
It also works if I just change the inheritance AsynchIO ->
DispatchHandle to public.
Any idea about what could be happening?
Best regards.
--
Manuel.