We've changed the way that objects are destroyed during shutdown to a
2-phase mechanism. First, destructors are called for all of the objects in
the store (in no particular order). Afterwards - the object storage and
the various symbol tables are destroyed&freed.
This has several implications:
-
The dependency problems during shutdown which could cause destructors
not to be called under certain circumstances - are gone now. Destructors
are always called for all objects, and you can depend on that. -
A VERY important implication is that you cannot, and must not rely in
any way on the order of destruction during shutdown. It runs in no
particular order. That means that by the time the destructor for your
object $foo is called, a reference to some other object $bar may already
be post-destruction. Note that it will still be 'intact' and accessible in
the sense that if you access it - there won't be crashes. However, if this
object does indeed have a destructor, it can be considered semantically
wrong to touch this object at this point. -
The APIs have changed to allow for this new mechanism. Instead of the
previous dtor callback, which was supposed to both call the destructor and
free the object's storage, there are now two separate callbacks - dtor
(call the destructor) and free_storage (guess). Generally, for classes
which implement PHP-style objects, you should implement both of these
callbacks (though you can probably use the standard dtor callback). For
overloaded classes such as SimpleXML, COM, etc. - you will most likely only
have to implement the free_storage callback, as there's no destructor
per-se. We already went over all the overloaded classes in the php-src CVS
and moved most of the dtor callbacks to free_storage. Note that the
interface is slightly different between these two callbacks - free_storage
doesn't receive the object handle. -
Last but not least - bug #25541 is now fixed! :)
Andi
- The APIs have changed to allow for this new mechanism. Instead of the
previous dtor callback, which was supposed to both call the destructor and
free the object's storage, there are now two separate callbacks - dtor
(call the destructor) and free_storage (guess). Generally, for classes
which implement PHP-style objects, you should implement both of these
callbacks (though you can probably use the standard dtor callback). For
overloaded classes such as SimpleXML, COM, etc. - you will most likely only
have to implement the free_storage callback, as there's no destructor
per-se. We already went over all the overloaded classes in the php-src CVS
and moved most of the dtor callbacks to free_storage. Note that the
interface is slightly different between these two callbacks - free_storage
doesn't receive the object handle.
Is there an automatic call to __destruct() method then? Because I'd like
my PHP-GTK objects to have that method called upon destruction and I
don't feel like reimplementing the mechanism for doing that.
- Andrei
Hi Andi,
Andi Gutmans wrote:
[...]
This has several implications:
[...]
- A VERY important implication is that you cannot, and must not
rely in any way on the order of destruction during shutdown. It runs in
no particular order. That means that by the time the destructor for
your object $foo is called, a reference to some other object $bar may
already be post-destruction. Note that it will still be 'intact' and
accessible in the sense that if you access it - there won't be crashes.
However, if this object does indeed have a destructor, it can be
considered semantically wrong to touch this object at this point.
Doesn't that render more sophisticated cases of objects with
constructors sort of unusable? I mean, any scheme like
class Wrapper:
ctor: $this->m_resource=alloc_resource();
dtor: $this->m_resource=free_resource();
doWork(): do_this_and_that($this->m_resource);
class Client:
ctor: $this->m_wrapper=new Wrapper();
dtor: $this->m_wrapper->doWork();
is inherently unsafe, unless I totally got your message wrong (apologies
for potential confusion).
If you consider a common case such as the wrapper class wrapping a db
connection or a file handle, and the client's destructor logging some
"shutdown" message using that wrapper, I fail to realize how this would
work with the given destructor scheme.
I'm not too familiar with the old destruction scheme, but wouldn't a
destruction scheme in which not all object destructors are called still
be superior to one which is completely non-deterministic in terms of
shutdown order? Or probably better, how about at least trying to
shutdown in reverse creation order (and for all cases for which that
won't work, use the new non-deterministic scheme)?
[...]
Cheers,
Michael
PS: Apologies for obvious stupid remarks in this post, I'm sure I'm
missing 1+ obvious issues
At 23:45 04/02/2004, Andrei Zmievski wrote:
- The APIs have changed to allow for this new mechanism. Instead of the
previous dtor callback, which was supposed to both call the destructor and
free the object's storage, there are now two separate callbacks - dtor
(call the destructor) and free_storage (guess). Generally, for classes
which implement PHP-style objects, you should implement both of these
callbacks (though you can probably use the standard dtor callback). For
overloaded classes such as SimpleXML, COM, etc. - you will most likely
only
have to implement the free_storage callback, as there's no destructor
per-se. We already went over all the overloaded classes in the php-src
CVS
and moved most of the dtor callbacks to free_storage. Note that the
interface is slightly different between these two callbacks - free_storage
doesn't receive the object handle.Is there an automatic call to __destruct() method then? Because I'd like
my PHP-GTK objects to have that method called upon destruction and I
don't feel like reimplementing the mechanism for doing that.
If it's a PHP-style object, then you can use zend_objects_destroy_object as
your destructor callback (when calling zend_objects_store_put()), in which
case __destruct() will be called. That's how the regular PHP objects do it.
Zeev
Hello Zeev,
Thursday, February 5, 2004, 12:24:47 AM, you wrote:
At 23:45 04/02/2004, Andrei Zmievski wrote:
- The APIs have changed to allow for this new mechanism. Instead of the
previous dtor callback, which was supposed to both call the destructor and
free the object's storage, there are now two separate callbacks - dtor
(call the destructor) and free_storage (guess). Generally, for classes
which implement PHP-style objects, you should implement both of these
callbacks (though you can probably use the standard dtor callback). For
overloaded classes such as SimpleXML, COM, etc. - you will most likely
only
have to implement the free_storage callback, as there's no destructor
per-se. We already went over all the overloaded classes in the php-src
CVS
and moved most of the dtor callbacks to free_storage. Note that the
interface is slightly different between these two callbacks - free_storage
doesn't receive the object handle.Is there an automatic call to __destruct() method then? Because I'd like
my PHP-GTK objects to have that method called upon destruction and I
don't feel like reimplementing the mechanism for doing that.
If it's a PHP-style object, then you can use zend_objects_destroy_object as
your destructor callback (when calling zend_objects_store_put()), in which
case __destruct() will be called. That's how the regular PHP objects do it.
So my guess is that for most internal objects we need to do so?
--
Best regards,
Marcus mailto:helly@php.net