From 3d016d8224993b0a89038ae8799baf4748dc97ca Mon Sep 17 00:00:00 2001 From: Kyle Suarez Date: Mon, 2 Nov 2015 20:34:11 -0500 Subject: [PATCH] CDRIVER-852 add timeout to gridfs readv/writev This adds a timeout, in milliseconds, to mongoc_gridfs_file_readv() and _writev(). If the timeout is reached before the action has completed fully, readv() and writev() will return the number of bytes actually read or written, respectively, and errno is set to ETIMEDOUT. A timeout of 0 indicates that no timeout will be used. A future commit must add tests for these timeouts to test-mongoc-gridfs.c. --- src/mongoc/mongoc-gridfs-file.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/mongoc/mongoc-gridfs-file.c b/src/mongoc/mongoc-gridfs-file.c index 195df93..07eb225 100644 --- a/src/mongoc/mongoc-gridfs-file.c +++ b/src/mongoc/mongoc-gridfs-file.c @@ -411,6 +411,7 @@ mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, int32_t r; size_t i; uint32_t iov_pos; + int64_t expire_at; ENTRY; @@ -419,7 +420,10 @@ mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, BSON_ASSERT (iovcnt); BSON_ASSERT (timeout_msec <= INT_MAX); - /* TODO: we should probably do something about timeout_msec here */ + /* determine when to stop reading */ + if (timeout_msec) { + expire_at = bson_get_monotonic_time () + (int64_t)(timeout_msec * 1000); + } /* Reading when positioned past the end does nothing */ if (file->pos >= file->length) { @@ -435,6 +439,12 @@ mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, iov_pos = 0; for (;; ) { + /* stop reading if we've exceeded the timeout */ + if (timeout_msec && bson_get_monotonic_time () >= expire_at) { + errno = ETIMEDOUT; + RETURN (bytes_read); + } + r = _mongoc_gridfs_file_page_read (file->page, (uint8_t *)iov[i].iov_base + iov_pos, (uint32_t)(iov[i].iov_len - iov_pos)); @@ -475,6 +485,7 @@ mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, int32_t r; size_t i; uint32_t iov_pos; + int64_t expire_at; ENTRY; @@ -483,7 +494,10 @@ mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, BSON_ASSERT (iovcnt); BSON_ASSERT (timeout_msec <= INT_MAX); - /* TODO: we should probably do something about timeout_msec here */ + /* determine when to stop writing */ + if (timeout_msec) { + expire_at = bson_get_monotonic_time () + (int64_t)(timeout_msec * 1000); + } /* Pull in the correct page */ if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { @@ -499,6 +513,12 @@ mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, iov_pos = 0; for (;; ) { + /* stop writing if the timeout is exceeded */ + if (timeout_msec && bson_get_monotonic_time () >= expire_at) { + errno = ETIMEDOUT; + RETURN (bytes_written); + } + if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { return -1; } -- 2.4.9 (Apple Git-60)