If there are no (ultra last) objections, I'll roll 5.0.5 tomorrow morning
(.il/Europe time) and post it in the evening.
Zeev
Zeev Suraski wrote:
If there are no (ultra last) objections, I'll roll 5.0.5 tomorrow
morning (.il/Europe time) and post it in the evening.Zeev
I'm still objecting to a patch by Jani made in April to move destructor
before shutdown functions. It was in response to the following report,
http://bugs.php.net/bug.php?id=30578
The problem being other than the fact that it's broken some BC is that
when it comes around to using the shutdown function any objects you
might actually have wished to use have since had their destructor called
closing connections and finalising data.
All I am proposing is that the shutdown function is run prior to
destruct functions being called as I don't expect to still be able to
access objects after the destructor is called which is still the case.
Changing the order doesn't effect bug 30578 which it was fixing.
The attached code demonstrates the problem, I'd expect to get the
following output
__construct
execution
execution
__destruct
the shutdown function checking the last step run, unfortunately I get
__construct
execution
__destruct
__destruct
Even though the destructor has been called I can still access the object
and fetch the value of the step variable.
Scott
I agree. Having no access MySQL(i) during shutdown has already broken
scripts I've used. Thankfully, Jani mentioned the change so I no
longer felt like I was going crazy, and I was able to work around it
by creating a "shutdown object" that contained references to all the
objects it might need, and then used it's destroy call. Same issue in
5.1.
If the behavior is to change from what we expect, I'd propose that we
add something to the manual. That said, I only found this problem
because of strange Fatal Error in Unknown on line 0 errors in the
error log. It took me a while to link that to the change in shutdown
behavior, and I don't think too many will be able to make the link
between the two.
My $0.02.
-steve--
Zeev Suraski wrote:
If there are no (ultra last) objections, I'll roll 5.0.5 tomorrow
morning (.il/Europe time) and post it in the evening.Zeev
I'm still objecting to a patch by Jani made in April to move destructor
before shutdown functions. It was in response to the following report,
http://bugs.php.net/bug.php?id=30578The problem being other than the fact that it's broken some BC is that
when it comes around to using the shutdown function any objects you
might actually have wished to use have since had their destructor called
closing connections and finalising data.All I am proposing is that the shutdown function is run prior to
destruct functions being called as I don't expect to still be able to
access objects after the destructor is called which is still the case.
Changing the order doesn't effect bug 30578 which it was fixing.The attached code demonstrates the problem, I'd expect to get the
following output__construct
execution
execution
__destructthe shutdown function checking the last step run, unfortunately I get
__construct
execution
__destruct
__destructEven though the destructor has been called I can still access the object
and fetch the value of the step variable.Scott
<?php
error_reporting(E_ALL);
class example
{
var $step;
function __construct()
{
echo "__construct\n";
$this->step = '__construct';
}
function execution()
{
echo "execution\n";
$this->step = 'execution';
}
function __destruct()
{
echo "__destruct\n";
$this->step = '__destruct';
}
}
echo "<pre>";
$obj = new example();
$obj->execution();function shutdown()
{
global $obj;
echo $obj->step . "\n";
}
register_shutdown_function('shutdown');
?>Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.648
diff -u -r1.648 main.c
--- main/main.c 2 Sep 2005 14:08:09 -0000 1.648
+++ main/main.c 6 Sep 2005 13:12:22 -0000
@@ -1319,16 +1319,16 @@
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
/* 1. Call all possible __destruct() functions */
/* 1. Call all possible shutdown functions registered with `register_shutdown_function()` */
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible __destruct() functions */ zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try();
/* 2. Call all possible shutdown functions registered with `register_shutdown_function()` */
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 3. Flush all output buffers */ zend_try { php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1) TSRMLS_CC);
Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.604.2.22
diff -u -r1.604.2.22 main.c
--- main/main.c 16 Aug 2005 18:11:34 -0000 1.604.2.22
+++ main/main.c 6 Sep 2005 13:34:15 -0000
@@ -1194,14 +1194,14 @@
sapi_send_headers(TSRMLS_C);
} zend_end_try();
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try();
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
if (PG(modules_activated)) { zend_deactivate_modules(TSRMLS_C); php_free_shutdown_functions(TSRMLS_C);
Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.640.2.4
diff -u -r1.640.2.4 main.c
--- main/main.c 2 Sep 2005 14:05:45 -0000 1.640.2.4
+++ main/main.c 6 Sep 2005 13:17:14 -0000
@@ -1200,16 +1200,16 @@
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
/* 1. Call all possible __destruct() functions */
/* 1. Call all possible shutdown functions registered with `register_shutdown_function()` */
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible __destruct() functions */ zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try();
/* 2. Call all possible shutdown functions registered with `register_shutdown_function()` */
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 3. Flush all output buffers */ zend_try { php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1) TSRMLS_CC);
The real solution is to have a two-phased shutdown sequence in PHP 6
because we're constantly "Fixing" the shutdown due to chicken&egg problem.
At 11:19 AM 9/6/2005, steve wrote:
I agree. Having no access MySQL(i) during shutdown has already broken
scripts I've used. Thankfully, Jani mentioned the change so I no
longer felt like I was going crazy, and I was able to work around it
by creating a "shutdown object" that contained references to all the
objects it might need, and then used it's destroy call. Same issue in
5.1.If the behavior is to change from what we expect, I'd propose that we
add something to the manual. That said, I only found this problem
because of strange Fatal Error in Unknown on line 0 errors in the
error log. It took me a while to link that to the change in shutdown
behavior, and I don't think too many will be able to make the link
between the two.My $0.02.
-steve--
Zeev Suraski wrote:
If there are no (ultra last) objections, I'll roll 5.0.5 tomorrow
morning (.il/Europe time) and post it in the evening.Zeev
I'm still objecting to a patch by Jani made in April to move destructor
before shutdown functions. It was in response to the following report,
http://bugs.php.net/bug.php?id=30578The problem being other than the fact that it's broken some BC is that
when it comes around to using the shutdown function any objects you
might actually have wished to use have since had their destructor called
closing connections and finalising data.All I am proposing is that the shutdown function is run prior to
destruct functions being called as I don't expect to still be able to
access objects after the destructor is called which is still the case.
Changing the order doesn't effect bug 30578 which it was fixing.The attached code demonstrates the problem, I'd expect to get the
following output__construct
execution
execution
__destructthe shutdown function checking the last step run, unfortunately I get
__construct
execution
__destruct
__destructEven though the destructor has been called I can still access the object
and fetch the value of the step variable.Scott
<?php
error_reporting(E_ALL);
class example
{
var $step;
function __construct()
{
echo "__construct\n";
$this->step = '__construct';
}
function execution()
{
echo "execution\n";
$this->step = 'execution';
}
function __destruct()
{
echo "__destruct\n";
$this->step = '__destruct';
}
}
echo "<pre>";
$obj = new example();
$obj->execution();function shutdown()
{
global $obj;
echo $obj->step . "\n";
}
register_shutdown_function('shutdown');
?>Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.648
diff -u -r1.648 main.c
--- main/main.c 2 Sep 2005 14:08:09 -0000 1.648
+++ main/main.c 6 Sep 2005 13:12:22 -0000
@@ -1319,16 +1319,16 @@
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
/* 1. Call all possible __destruct() functions */
/* 1. Call all possible shutdown functions registered
with
register_shutdown_function()
*/
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible __destruct() functions */ zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try();
/* 2. Call all possible shutdown functions registered
with
register_shutdown_function()
*/
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 3. Flush all output buffers */ zend_try {
php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1) TSRMLS_CC);
Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.604.2.22
diff -u -r1.604.2.22 main.c
--- main/main.c 16 Aug 2005 18:11:34 -0000 1.604.2.22
+++ main/main.c 6 Sep 2005 13:34:15 -0000
@@ -1194,14 +1194,14 @@
sapi_send_headers(TSRMLS_C);
} zend_end_try();
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try();
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
if (PG(modules_activated)) { zend_deactivate_modules(TSRMLS_C); php_free_shutdown_functions(TSRMLS_C);
Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.640.2.4
diff -u -r1.640.2.4 main.c
--- main/main.c 2 Sep 2005 14:05:45 -0000 1.640.2.4
+++ main/main.c 6 Sep 2005 13:17:14 -0000
@@ -1200,16 +1200,16 @@
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
/* 1. Call all possible __destruct() functions */
/* 1. Call all possible shutdown functions registered
with
register_shutdown_function()
*/
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible __destruct() functions */ zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try();
/* 2. Call all possible shutdown functions registered
with
register_shutdown_function()
*/
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 3. Flush all output buffers */ zend_try {
php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1) TSRMLS_CC);
The real solution is to have a two-phased shutdown sequence in PHP 6 because
we're constantly "Fixing" the shutdown due to chicken&egg problem.
But we have that, just no extensions are using it... What I do think
that we need to do is to call the shutdown handlers before the dtors,
now we do it the "wrong" way around making things less flexible. And,
IMO, that can not affect much (and we'd restore BC with PHP <= 5.0.4).
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Derick Rethans wrote:
The real solution is to have a two-phased shutdown sequence in PHP 6 because
we're constantly "Fixing" the shutdown due to chicken&egg problem.But we have that, just no extensions are using it... What I do think
that we need to do is to call the shutdown handlers before the dtors,
now we do it the "wrong" way around making things less flexible. And,
IMO, that can not affect much (and we'd restore BC with PHP <= 5.0.4).
I do belive that we should have kept BC here and allow use of objects in
shutdown functions, ie. call them before calling object destructors.
Edin
EK>>> But we have that, just no extensions are using it... What I do think
Well, I guess they'd better start to use then :)
EK>>> that we need to do is to call the shutdown handlers before the dtors,
EK>>> now we do it the "wrong" way around making things less flexible. And,
I don't see how having two stages "before dtors" and "after dtors" is less
flexible than having only one of them.
EK>>I do belive that we should have kept BC here and allow use of objects
EK>>in shutdown functions, ie. call them before calling object
EK>>destructors.
We have classical c&e problem here - if we defer dtors to after shutdowns,
they couldn't do things like close files, finalize DB connections, etc.
Many people think dtors are meant to do that.
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
EK>>I do belive that we should have kept BC here and allow use of objects
EK>>in shutdown functions, ie. call them before calling object
EK>>destructors.We have classical c&e problem here - if we defer dtors to after shutdowns,
they couldn't do things like close files, finalize DB connections, etc.
Many people think dtors are meant to do that.
But they can still do that.. With "shutdown functions" I meant functions
registered with register_shutdown_function()
.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
DR>>But they can still do that.. With "shutdown functions" I meant
DR>>functions registered with register_shutdown_function()
.
Ah... This is smaller problem - register_shutdown_function()
ones can be
called on "before dtors" stage.
--
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
DR>>But they can still do that.. With "shutdown functions" I meant
DR>>functions registered withregister_shutdown_function()
.Ah... This is smaller problem -
register_shutdown_function()
ones can be
called on "before dtors" stage.
Indeed, we've always done this too... I've a patch ready to commit for
PHP 5.1/6.0 for this:
diff -u -p -d -r1.640 main.c
--- main.c 5 Aug 2005 21:44:26 -0000 1.640
+++ main.c 8 Sep 2005 11:33:43 -0000
@@ -1197,16 +1197,16 @@ void php_request_shutdown(void *dummy)
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
-
/* 1. Call all possible __destruct() functions */
-
zend_try {
-
zend_call_destructors(TSRMLS_C);
-
} zend_end_try();
-
/* 2. Call all possible shutdown functions registered with `register_shutdown_function()` */
-
/* 1. Call all possible shutdown functions registered with `register_shutdown_function()` */ if (PG(modules_activated)) zend_try { php_call_shutdown_functions(TSRMLS_C); } zend_end_try();
-
/* 2. Call all possible __destruct() functions */
-
zend_try {
-
zend_call_destructors(TSRMLS_C);
-
} zend_end_try();
-
/* 3. Flush all output buffers */ zend_try { php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1) TSRMLS_CC);
Derick
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Path for 5.0.6, it would seem odd to have a different behavior on the
5.0.x branch.
Scott
Derick Rethans wrote:
DR>>But they can still do that.. With "shutdown functions" I meant
DR>>functions registered withregister_shutdown_function()
.Ah... This is smaller problem -
register_shutdown_function()
ones can be
called on "before dtors" stage.Indeed, we've always done this too... I've a patch ready to commit for
PHP 5.1/6.0 for this:diff -u -p -d -r1.640 main.c
--- main.c 5 Aug 2005 21:44:26 -0000 1.640
+++ main.c 8 Sep 2005 11:33:43 -0000
@@ -1197,16 +1197,16 @@ void php_request_shutdown(void *dummy)
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
/* 1. Call all possible __destruct() functions */
zend_try {
zend_call_destructors(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible shutdown functions registered with `register_shutdown_function()` */
/* 1. Call all possible shutdown functions registered with `register_shutdown_function()` */ if (PG(modules_activated)) zend_try { php_call_shutdown_functions(TSRMLS_C); } zend_end_try();
/* 2. Call all possible __destruct() functions */
zend_try {
zend_call_destructors(TSRMLS_C);
} zend_end_try();
/* 3. Flush all output buffers */ zend_try { php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1) TSRMLS_CC);
Derick
Any chance of getting these applied to 5.0.x and 5.1?
Scott
Scott MacVicar wrote:
Path for 5.0.6, it would seem odd to have a different behavior on the
5.0.x branch.Scott
Derick Rethans wrote:
DR>>But they can still do that.. With "shutdown functions" I meant
DR>>functions registered withregister_shutdown_function()
.Ah... This is smaller problem -
register_shutdown_function()
ones can
be called on "before dtors" stage.Indeed, we've always done this too... I've a patch ready to commit for
PHP 5.1/6.0 for this:diff -u -p -d -r1.640 main.c
--- main.c 5 Aug 2005 21:44:26 -0000 1.640
+++ main.c 8 Sep 2005 11:33:43 -0000
@@ -1197,16 +1197,16 @@ void php_request_shutdown(void *dummy)
EG(opline_ptr) = NULL;
EG(active_op_array) = NULL;
/* 1. Call all possible __destruct() functions */
zend_try {
zend_call_destructors(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible shutdown functions registered with
register_shutdown_function()
*/
/* 1. Call all possible shutdown functions registered with
register_shutdown_function()
*/
if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
} zend_end_try();
/* 2. Call all possible __destruct() functions */
zend_try {
zend_call_destructors(TSRMLS_C);
} zend_end_try();
/* 3. Flush all output buffers */ zend_try {
php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1)
TSRMLS_CC);Derick
Index: main/main.c
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.604.2.22
diff -u -r1.604.2.22 main.c
--- main/main.c 16 Aug 2005 18:11:34 -0000 1.604.2.22
+++ main/main.c 6 Sep 2005 13:34:15 -0000
@@ -1194,14 +1194,14 @@
sapi_send_headers(TSRMLS_C);
} zend_end_try();
- if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
- } zend_end_try();
- zend_try {
zend_call_destructors(TSRMLS_C);
} zend_end_try();
- if (PG(modules_activated)) zend_try {
php_call_shutdown_functions(TSRMLS_C);
- } zend_end_try();
- if (PG(modules_activated)) {
zend_deactivate_modules(TSRMLS_C);
php_free_shutdown_functions(TSRMLS_C);
Any chance of getting these applied to 5.0.x and 5.1?
Yes, it's on my todo list - will do that when I get back home.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Path for 5.0.6, it would seem odd to have a different behavior on the 5.0.x
branch.
Committed.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org