facebook/hhvm — pull request #3279 by danslo (2014-07-25 20:19:05+00:00)
Title: run shutdown handlers before onSendEnd

I am sending this as a PR to get this into phabricator as a means to get
feedback on this particular issue. It's been hard to get a hold of
someone on github :)

Context:
- hphp_context_exit does a bunch of cleanup that includes calling object
destructors, running extension shutdown handlers, and some other
cleanup.
- register_postsend_function is a FB/HHVM specific function that
registers a callback to be executed after response has been sent.

Problem:
- midway through hphp_context_exit, user code is no longer allowed to
be run, so it had to be called before register_postend_function.
- register_postsend_function obviously has to be called after onSendEnd.
- however, hphp_context_exit may invoke user code (ex. object
destructors can send output when Eval.EnableObjDestructCall is
enabled.
This causes a circular reference problem, which is currently preventing
output from live-at-end-of-request object destructors.

Proposed solution:
- add hphp_context_shutdown and have it run all the shutdown handlers.
- run hphp_context_shutdown before onSendEnd
- run hphp_context_exit after onSendEnd and onShutdownPostSend (where
the latter runs the callback registered through
register_postsend_function)

Side-effect:
This effectively means that when using the runtime option listed above,
object destructors will be called before register_postsend_function callback.
This is inevitable because of reasons listed above: destructors may send output.
I don't expect this to be a major issue, because the runtime option is
disabled by default.

p.s. The problem only really occured in the http and RPC request-handlers
because of the calls to onSendEnd, but I have also moved around the shutdown in
other places (for example, to be run before onShutdownPostSend) for
consistency.

Closes #3062.