-----Original Message-----
From: [email protected] [mailto:tech-talk-
[email protected]] On Behalf Of Mark Rivers
Sent: Tuesday, September 13, 2011 1:27 PM
To: Till Straumann; EPICS Techtalk
Subject: RE: asynMotorController exception safety
...
If your constructor throws an exception, does that automatically
result
in a call to the destructor for the base classes?
Absolutely yes.
If the constructor of an object (or sub-object) completes then its
destructor will be called. Sub-objects may be base classes, or member
objects. This behavior why container classes can effectively manage
resources.
I think the basic problem is that asyn ports can't be unregistered.
When the asynPortDriver instance is destroyed it frees its
asynStandardInterfaces member structure. This leaves asynManager
holding invalid pointers.
@Till, When I face this situation I set a flag if the constructor fails
which prevents the port from ever connecting. Something like:
class myport : asynPortDriver {
bool zombie;
...
}
myport::myport()
: zombie(false)
{
try {
// normal initialization
}catch(...){
zombie=true;
}
}
myport::connect(){
if(zombie)
return asynError;
}
A better solution would be to avoid freeing asynStandardInterfaces.
Michael
I would not have
thought so, but I'm not enough of a C++ expert to know the answer to
that.
Mark
-----Original Message-----
From: Till Straumann [mailto:[email protected]]
Sent: Tuesday, September 13, 2011 11:40 AM
To: EPICS Techtalk; Mark Rivers
Subject: asynMotorController exception safety
I wrote a driver class derived from asynMotorController
(which BTW was easy, thanks for the great package).
I would like the driver to be robust in case e.g., of the
absence of e.g., hardware or a serial communication channel.
Hence, my class does something like:
class MyDrv : public asynMotorController {
public:
MyDrv() : asynMotorController(<parameters go here>)
{
status = detect_hardware(<parameters>);
if ( status ) {
throw MyException("HW detection failed\n");
}
}
};
In my main application I create a driver object
try {
new MyDrv();
} catch (MyException&e) {
printf("Unable to create driver: %s\n", e.what());
}
However, if hardware detection fails and the exception
is thrown and subsequently caught then the IOC application
will eventually (later) segfault in asynPortDriver::callbackTask()
(when trying to lock the mutex). It seems that the work
of the superclass constructor(s)
(asynMotorController/asynPortDriver/...) is
not properly undone.
No segfault happens if I comment the entire try block
(including the 'new' statement), i.e., if I create no
driver at all (but still load the .db file etc.).
How am I supposed to handle failure in the constructor?
Thanks
-- Till