-
Notifications
You must be signed in to change notification settings - Fork 504
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests are working fine (IPv6 needs a fix in #820 ), I haven't tested any added functionality yet.
src/socket.c
Outdated
int eno = php_socket_errno(); \ | ||
(socket)->error = eno; \ | ||
PTHREADS_HANDLE_SOCKET_ERROR(eno); \ | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about other compilers, but this doesn't register as valid with MSVC (fails to compile). A do {} while(0)
works.
classes/socket.h
Outdated
@@ -66,22 +69,22 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(Socket_listen, 0, 1, _IS_BOOL, 0) | |||
ZEND_ARG_TYPE_INFO(0, backlog, IS_LONG, 0) | |||
ZEND_END_ARG_INFO() | |||
|
|||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(Socket_connect, 0, 2, _IS_BOOL, 0) | |||
ZEND_BEGIN_ARG_INFO_EX(Socket_connect, 0, 0, 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't look like it needs changes?
classes/socket.h
Outdated
@@ -111,18 +114,23 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(Socket_getHost, 0, 0, IS_ARRAY, 0) | |||
ZEND_ARG_TYPE_INFO(0, port, _IS_BOOL, 0) | |||
ZEND_END_ARG_INFO() | |||
|
|||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(Socket_select, 0, 3, IS_LONG, 0) | |||
ZEND_BEGIN_ARG_INFO_EX(Socket_select, 0, 0, 4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the code the sec
parameter still appears to be optional, so the required argcount should be 3.
classes/socket.h
Outdated
@@ -215,7 +225,7 @@ PHP_METHOD(Socket, listen) { | |||
pthreads_socket_listen(getThis(), backlog, return_value); | |||
} /* }}} */ | |||
|
|||
/* {{{ proto Socket Socket::accept([string class = self::class]) */ | |||
/* {{{ proto Socket/bool Socket::accept([string class = self::class]) */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the separator ought to be |
.
src/socket.c
Outdated
if(threaded->store.sock->error == SUCCESS) { | ||
RETURN_FALSE; | ||
} | ||
ZVAL_LONG(return_value, threaded->store.sock->error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the RETVAL_LONG
macro could be used here
src/socket.c
Outdated
fd_set rfds, wfds, efds; | ||
php_socket_t mfd = 0; | ||
int result = SUCCESS, sets = 0; | ||
struct timeval tv; | ||
|
||
zval_dtor(errorno); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be zval_ptr_dtor
, otherwise it will leak on cyclic references.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally this will segfault if the errorno
parameter is not given.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've copied this part from
Line 775 in d32079f
zval_dtor(port); |
zval_dtor
in pthreads_socket_recvfrom
also faulty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks as though all three variables are not being properly freed:
Lines 773 to 775 in d32079f
zval_dtor(buffer); | |
zval_dtor(name); | |
zval_dtor(port); |
They should all be using zval_ptr_dtor
here (and elsewhere in pthreads_socket_recvfrom
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. zval_dtor
was replaced by zval_ptr_dtor
. Maybe you could have a look at the original implementation of socket_recvfrom
https://github.com/php/php-src/blob/master/ext/sockets/sockets.c#L1771 which uses zval_dtor
too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll have a look into this, thanks.
if (eno != SUCCESS) { \ | ||
if (estr) { \ | ||
efree(estr); \ | ||
#define PTHREADS_HANDLE_SOCKET_ERROR(eno) do { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conventionally, parentheses should be placed around eno
in the macro body.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parentheses added, should be fixed
src/socket.c
Outdated
@@ -947,7 +947,7 @@ void pthreads_socket_get_last_error(zval *object, zend_bool clear, zval *return_ | |||
if(threaded->store.sock->error == SUCCESS) { | |||
RETURN_FALSE; | |||
} | |||
ZVAL_LONG(return_value, threaded->store.sock->error); | |||
RETURN_LONG(threaded->store.sock->error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will not work as expected (the block below won't be executed), did you mean RETVAL_LONG
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, you're right. RETURN_LONG
contains a return;
. My fault.
@sirsnyder from a non-technical perspective I don't see anything immediately wrong with it, except for |
} \ | ||
return; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this return statement prevent the return_value
from being set to false
later on?
Lines 741 to 743 in f15c95e
PTHREADS_HANDLE_SOCKET_ERROR(eno); | |
RETURN_FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also in the PTHREADS_SOCKET_ERROR
call sites.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of an exception, there is no need to set a return value or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite true. I overlooked that part...
I've had another look through the code, and cannot see anything immediately wrong with it (other than the couple of comments I left). Assuming @dktapps doesn't notice any further problems, then feel free to merge. Also, more tests around the sockets functionality (testing both success and error paths) would be good. |
if (estr) { \ | ||
efree(estr); \ | ||
#define PTHREADS_HANDLE_SOCKET_ERROR(eno) do { \ | ||
if ((eno) != EAGAIN && (eno) != EWOULDBLOCK && (eno) != EINPROGRESS && (eno) != SOCK_EINVAL) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EWOULDBLOCK
was written to be conditionally used lower down. Will it always be available? If not, then it should be conditionally used here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On modern unix systems with GNU C library EWOULDBLOCK
is always available with same value of EAGAIN. On modern windows systems EWOULDBLOCK
is available but Microsoft do not want to guarantee EWOULDBLOCK
. I've changed that. If error no EWOULDBLOCK
doesn't exist on win32, it will be defined.
@tpunt more tests will come |
The return type of the following methods had to be removed from zend arg info, because these methods can return bool(
false
) in case of an error:The two methods
recvfrom()
andsendto()
can also return bool(false
) in case of an error, but there were no explicit return types defined.Each Socket object holds his own error state now. To query and clear the error state, the two new methods
getLastError()
andclearError()
were added. MethodgetLastError()
differs from the PHP equivalentsocket_last_error()
by one param. Paramclear
was added to query and clear error state in one single method call. The param is optional andfalse
by default.I've tried to mimic the PHP socket error behavior(without warnings) with a view to blocking/non-blocking mode as far as possible.
Socket::select()
should also not throw exceptions in case of an error. But this method is static and there is no global Socket error state. Therefore a optional paramerror
was added toSocket::select()
to retrieve a possible error.Two -win32 socket tests where removed. @dktapps could you test the both socket-sentto-recvfrom- tests on windows, please?