Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed PHP-693: MongoCursor timeout not used when reading data

  • Loading branch information...
commit 11a40aae5376c9172c5ebe98b48a001c895e085c 1 parent 7d49c63
Hannes Magnusson bjori authored derickr committed
4 cursor.c
View
@@ -103,7 +103,7 @@ static signed int get_cursor_header(mongo_connection *con, mongo_cursor *cursor,
php_mongo_log(MLOG_IO, MLOG_FINE TSRMLS_CC, "getting cursor header");
client = (mongoclient*)zend_object_store_get_object(cursor->resource TSRMLS_CC);
- status = client->manager->recv_header(con, NULL, buf, REPLY_HEADER_LEN, error_message);
+ status = client->manager->recv_header(con, &client->servers->options, cursor->timeout, buf, REPLY_HEADER_LEN, error_message);
/* socket has been closed */
if (status == 0) {
*error_message = strdup("socket has been closed");
@@ -166,7 +166,7 @@ static int get_cursor_body(mongo_connection *con, mongo_cursor *cursor, char **e
cursor->buf.pos = cursor->buf.start;
/* finish populating cursor */
- return MonGlo(manager)->recv_data(con, &client->servers->options, cursor->buf.pos, cursor->recv.length, error_message);
+ return MonGlo(manager)->recv_data(con, &client->servers->options, cursor->timeout, cursor->buf.pos, cursor->recv.length, error_message);
}
/* Cursor helper function */
17 io_stream.c
View
@@ -97,11 +97,19 @@ void* php_mongo_io_stream_connect(mongo_con_manager *manager, mongo_server_def *
}
-int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message)
+int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
int num = 1, received = 0;
TSRMLS_FETCH();
+ if (timeout > 0 && options->socketTimeoutMS != timeout) {
+ struct timeval rtimeout = {0};
+ rtimeout.tv_sec = timeout / 1000;
+ rtimeout.tv_usec = (timeout % 1000) * 1000;
+
+ php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
+ }
+
/* this can return FAILED if there is just no more data from db */
while (received < size && num > 0) {
int len = 4096 < (size - received) ? 4096 : size - received;
@@ -119,6 +127,13 @@ int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *option
if (options && options->ctx) {
php_stream_notify_progress_increment((php_stream_context *)options->ctx, received, size);
}
+ if (timeout > 0 && options->socketTimeoutMS != timeout) {
+ struct timeval rtimeout = {0};
+ rtimeout.tv_sec = options->socketTimeoutMS / 1000;
+ rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000;
+
+ php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
+ }
return received;
}
2  io_stream.h
View
@@ -26,7 +26,7 @@
void* php_mongo_io_stream_connect(mongo_con_manager *manager, mongo_server_def *server, mongo_server_options *options, char **error_message);
-int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
+int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message);
int php_mongo_io_stream_send(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
void php_mongo_io_stream_close(mongo_connection *con, int why);
void php_mongo_io_stream_forget(mongo_con_manager *manager, mongo_connection *con);
4 mcon/connections.c
View
@@ -371,7 +371,7 @@ static int mongo_connect_send_packet(mongo_con_manager *manager, mongo_connectio
return -1;
}
mcon_str_ptr_dtor(packet);
- read = manager->recv_header(con, options, reply_buffer, MONGO_REPLY_HEADER_SIZE, &recv_error_message);
+ read = manager->recv_header(con, options, options->socketTimeoutMS, reply_buffer, MONGO_REPLY_HEADER_SIZE, &recv_error_message);
if (read == -1) {
*error_message = malloc(256);
snprintf(*error_message, 256, "send_package: error reading from socket: %s", recv_error_message);
@@ -402,7 +402,7 @@ static int mongo_connect_send_packet(mongo_con_manager *manager, mongo_connectio
/* Read data */
*data_buffer = malloc(data_size + 1);
- if (manager->recv_data(con, options, *data_buffer, data_size, error_message) <= 0) {
+ if (manager->recv_data(con, options, options->socketTimeoutMS, *data_buffer, data_size, error_message) <= 0) {
free(data_buffer);
return 0;
}
8 mcon/io.c
View
@@ -130,9 +130,9 @@ int mongo_io_send(mongo_connection *con, mongo_server_options *options, void *da
*
* On failure, the calling function is responsible for disconnecting
*/
-int mongo_io_recv_header(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message)
+int mongo_io_recv_header(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
- int status = mongo_io_wait_with_timeout((int) (long)con->socket, options ? options->socketTimeoutMS : 0, error_message);
+ int status = mongo_io_wait_with_timeout((int) (long)con->socket, timeout ? timeout : options->socketTimeoutMS, error_message);
if (status != 0) {
/* We don't care which failure it was, it just failed and the error_message has been set */
@@ -150,7 +150,7 @@ int mongo_io_recv_header(mongo_connection *con, mongo_server_options *options, v
return status;
}
-int mongo_io_recv_data(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message)
+int mongo_io_recv_data(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
int num = 1, received = 0;
@@ -158,7 +158,7 @@ int mongo_io_recv_data(mongo_connection *con, mongo_server_options *options, voi
while (received < size && num > 0) {
int len = 4096 < (size - received) ? 4096 : size - received;
- if (mongo_io_wait_with_timeout((int) (long) con->socket, options->socketTimeoutMS, error_message) != 0) {
+ if (mongo_io_wait_with_timeout((int) (long) con->socket, timeout ? timeout : options->socketTimeoutMS, error_message) != 0) {
/* We don't care which failure it was, it just failed */
return -1;
}
4 mcon/io.h
View
@@ -19,7 +19,7 @@
int mongo_io_wait_with_timeout(int sock, int to, char **error_message);
int mongo_io_send(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
-int mongo_io_recv_header(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
-int mongo_io_recv_data(mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
+int mongo_io_recv_header(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message);
+int mongo_io_recv_data(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message);
#endif
4 mcon/types.h
View
@@ -224,8 +224,8 @@ typedef struct _mongo_con_manager
/* IO callbacks, either using the 'native mcon' or external hooks (i.e. PHP Streams) */
void* (*connect) (struct _mongo_con_manager *manager, mongo_server_def *server, mongo_server_options *options, char **error_message);
- int (*recv_header) (mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
- int (*recv_data) (mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
+ int (*recv_header) (mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message);
+ int (*recv_data) (mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message);
int (*send) (mongo_connection *con, mongo_server_options *options, void *data, int size, char **error_message);
void (*close) (mongo_connection *con, int why);
void (*forget) (struct _mongo_con_manager *manager, mongo_connection *con);
Please sign in to comment.
Something went wrong with that request. Please try again.