Skip to content

Fix GH-18990, bug #81029, bug #47314: SOAP HTTP socket not closing on object destruction #19001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

nielsdos
Copy link
Member

@nielsdos nielsdos commented Jul 1, 2025

Currently the resource is attached to the object and its refcount is increased. This means that the refcount to the resource is 2 instead of 1 as expected. A refcount of 2 is necessary in the current code because of how the error handling works: by using convert_to_null() the resource actually goes to rc_dtor_func(), dropping its refcount to 1. So on error the refcount is correct.
To solve the issue, let stream conceptually be a borrow of the resource with refcount 1, and just use ZVAL_NULL() to prevent calling rc_dtor_func() on the resource.

… on object destruction

Currently the resource is attached to the object and its refcount is
increased. This means that the refcount to the resource is 2 instead of
1 as expected. A refcount of 2 is necessary in the current code because
of how the error handling works: by using convert_to_null() the resource
actually goes to rc_dtor_func(), dropping its refcount to 1. So on error
the refcount is correct.
To solve the issue, let `stream` conceptually be a borrow of the
resource with refcount 1, and just use ZVAL_NULL() to prevent calling
rc_dtor_func() on the resource.
@nielsdos nielsdos linked an issue Jul 1, 2025 that may be closed by this pull request
Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds reasonable, just one question

php_stream_auto_cleanup(stream);
ZVAL_RES(Z_CLIENT_HTTPSOCKET_P(this_ptr), stream->res);
GC_ADDREF(stream->res);
php_stream_to_zval(stream, Z_CLIENT_HTTPSOCKET_P(this_ptr));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the auto cleanup anymore ? (IDK what that function does)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That macro will also do the same thing that auto cleanup does:

php-src/main/php_streams.h

Lines 270 to 274 in 59dd0f8

#define php_stream_auto_cleanup(stream) { (stream)->__exposed = 1; }
/* use this to assign the stream to a zval and tell the stream that is
* has been exported to the engine; it will expect to be closed automatically
* when the resources are auto-destructed */
#define php_stream_to_zval(stream, zval) { ZVAL_RES(zval, (stream)->res); (stream)->__exposed = 1; }

Anyway, that "auto cleanup" name is a badly chosen name. It just means that the resource is exposed as a zval and will be cleaned up that way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right... that is indeed a bad name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants