Browse Source

Added ability to set timeout on socket read operations. New function

set_socket_timeout(socket, seconds, microseconds) sets the timeout.
@- Added ability to set timeout on socket read operations through
@ set_socket_timeout() function. (Andrei)
PHP-4.0.5
Andrei Zmievski 27 years ago
parent
commit
4423bf9d10
  1. 40
      ext/standard/file.c
  2. 28
      ext/standard/fsock.c
  3. 1
      ext/standard/fsock.h

40
ext/standard/file.c

@ -240,7 +240,7 @@ function_entry file_functions[] = {
PHP_FE(flock, NULL)
PHP_FE(get_meta_tags, NULL)
PHP_FE(set_socket_blocking, NULL)
#if (0 && defined(HAVE_SYS_TIME_H) && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO))
#if HAVE_SYS_TIME_H
PHP_FE(set_socket_timeout, NULL)
#endif
#if 0 /* needs to be rethought 991221 thies@digicol.de */
@ -879,32 +879,40 @@ PHP_FUNCTION(set_socket_blocking)
/* {{{ proto int set_socket_timeout(int socket descriptor, int timeout )
NYI */
#if (0 && defined(HAVE_SYS_TIME_H) && HAVE_SETSOCKOPT && defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO))
#if HAVE_SYS_TIME_H
/* this doesn't work, as it appears those properties are read-only :( */
PHP_FUNCTION(set_socket_timeout)
{
pval *socket,*timeout;
int type, *sock;
zval **socket, **seconds, **microseconds;
int type;
void *what;
int socketd = 0;
struct timeval t;
if (ARG_COUNT(ht)!=2 || zend_get_parameters(ht, 2, &socket, &timeout)==FAILURE) {
if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket, &seconds, &microseconds)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(socket);
convert_to_long(timeout);
what = zend_fetch_resource(socket, -1, "File-Handle", &type, 1, le_socket);
ZEND_VERIFY_RESOURCE(what);
socketd = *(int *)what;
sock = zend_list_find(socket->value.lval, &type);
if (type!=le_socket) {
php_error(E_WARNING,"%d is not a socket id",socket->value.lval);
RETURN_FALSE;
convert_to_long_ex(seconds);
t.tv_sec = (*seconds)->value.lval;
if (ZEND_NUM_ARGS() == 3) {
convert_to_long_ex(microseconds);
t.tv_usec = (*microseconds)->value.lval % 1000000;
t.tv_sec += (*microseconds)->value.lval / 1000000;
}
t.tv_sec = timeout->value.lval;
t.tv_usec = 0;
setsockopt(*sock,SOL_SOCKET,SO_SNDTIMEO,(void *) &t,sizeof(struct timeval));
setsockopt(*sock,SOL_SOCKET,SO_RCVTIMEO,(void *) &t,sizeof(struct timeval));
else
t.tv_usec = 0;
php_sockset_timeout(socketd, &t);
RETURN_TRUE;
}
#endif
#endif /* HAVE_SYS_TIME_H */
/* }}} */
/* {{{ proto string fgets(int fp, int length)

28
ext/standard/fsock.c

@ -116,6 +116,8 @@ struct php_sockbuf {
char persistent;
char is_blocked;
size_t chunk_size;
struct timeval timeout;
int timeout_event;
};
typedef struct php_sockbuf php_sockbuf;
@ -459,6 +461,7 @@ static php_sockbuf *php_sockcreate(int socket FLS_DC)
sock->persistent = persistent;
sock->is_blocked = 1;
sock->chunk_size = FG(def_chunk_size);
sock->timeout.tv_sec = -1;
FG(phpsockbuf) = sock;
return sock;
@ -528,13 +531,25 @@ int php_sock_close(int socket)
static void php_sockwait_for_data(php_sockbuf *sock)
{
fd_set fdr, tfdr;
int retval;
struct timeval timeout;
FD_ZERO(&fdr);
FD_SET(sock->socket, &fdr);
sock->timeout_event = 0;
while(1) {
tfdr = fdr;
if(select(sock->socket + 1, &tfdr, NULL, NULL, NULL) == 1)
timeout = sock->timeout;
if (timeout.tv_sec == -1)
retval = select(sock->socket + 1, &tfdr, NULL, NULL, NULL);
else {
retval = select(sock->socket + 1, &tfdr, NULL, NULL, &timeout);
if (retval == 0)
sock->timeout_event = 1;
}
if(retval == 1 || retval == 0)
break;
}
}
@ -555,6 +570,8 @@ static size_t php_sockread_internal(php_sockbuf *sock)
if(sock->is_blocked) {
php_sockwait_for_data(sock);
if (sock->timeout_event)
return 0;
}
/* read at a maximum sock->chunk_size */
@ -577,7 +594,7 @@ static size_t php_sockread_internal(php_sockbuf *sock)
static void php_sockread_total(php_sockbuf *sock, size_t maxread)
{
while(!sock->eof && TOREAD(sock) < maxread) {
while(!sock->eof && TOREAD(sock) < maxread && !sock->timeout_event) {
php_sockread_internal(sock);
}
}
@ -609,6 +626,13 @@ int php_sockset_blocking(int socket, int mode)
return old;
}
void php_sockset_timeout(int socket, struct timeval *timeout)
{
SOCK_FIND(sock, socket);
sock->timeout = *timeout;
}
#define SOCK_FIND_AND_READ_MAX(max) \
SOCK_FIND(sock, socket); \
if(sock->is_blocked) php_sockread_total(sock, max); else php_sockread(sock)

1
ext/standard/fsock.h

@ -67,6 +67,7 @@ int php_sock_feof(int socket);
int php_sock_fgetc(int socket);
int php_is_persistent_sock(int);
int php_sockset_blocking(int socket, int mode);
void php_sockset_timeout(int socket, struct timeval *timeout);
int php_sockdestroy(int socket);
int php_sock_close(int socket);
size_t php_sock_set_def_chunk_size(size_t size);

Loading…
Cancel
Save