On Sun, Aug 31, 2014 at 3:33 AM, Stas Malyshev <smalys...@sugarcrm.com> wrote:
> Hi! > > I was looking at bug https://bugs.php.net/bug.php?id=67644 and it looks > like we have a bit of a problem with output buffering and dtors on > shutdown. Basically, right now our code looks like this: > > /* 2. Call all possible __destruct() functions */ > zend_try { > zend_call_destructors(TSRMLS_C); > } zend_end_try(); > > /* 3. Flush all output buffers */ > zend_try { > > // And here we go flushing output buffers > > Now, since ob functions can have userland handlers, these handlers can > create new objects. And these objects will not benefit from orderly dtor > round that zend_call_destructors(TSRMLS_C) is providing - instead their > dtors will be called from zend_objects_store_free_object_storage() and > by then their environment may already be ruined and their dtors can not > run properly. > > OTOH, moving __destruct after output buffers may not be good either, as > dtors may output something. > > The problem seems to be resolved if I either duplicate > zend_call_destructors(TSRMLS_C); after the output buffers flushing or put > zend_objects_store_mark_destructed(&EG(objects_store) TSRMLS_CC); > there. > > Of course, the second solution has the downside of not calling the dtors > of objects that were created while flushing ob buffers. The > zend_call_destructors would work but since output buffering is supposed > to be shut down by then, I wonder if it won't also have bad consequences > if these dtors do something with output buffering. > > I'm leaning towards the second solution - if you create the objects so > late on shutdown stage, you shouldn't really expect them to be destroyed > normally, otherwise the cycle would never end. However, we could > consider the first option too. Any thoughts? > Instead of iterating through all objects and setting a flag, can't we set a global flag that object dtors are not called after this point? This both solves the issue of new objects being created after the fact and makes shutdown less expensive. Nikita