|
1 | 1 | // Copyright (c) Microsoft Corporation. All rights reserved.
|
2 | 2 | // SPDX-License-Identifier: MIT
|
3 | 3 |
|
| 4 | +#include "azure/core/platform.hpp" |
| 5 | + |
| 6 | +#if defined(AZ_PLATFORM_WINDOWS) |
| 7 | +#if !defined(WIN32_LEAN_AND_MEAN) |
| 8 | +#define WIN32_LEAN_AND_MEAN |
| 9 | +#endif |
| 10 | +#if !defined(NOMINMAX) |
| 11 | +#define NOMINMAX |
| 12 | +#endif |
| 13 | +#endif |
| 14 | + |
4 | 15 | #include "azure/core/http/curl_transport.hpp"
|
5 | 16 | #include "azure/core/http/http.hpp"
|
6 | 17 | #include "azure/core/http/policies/policy.hpp"
|
7 | 18 | #include "azure/core/http/transport.hpp"
|
8 | 19 | #include "azure/core/internal/diagnostics/log.hpp"
|
9 |
| -#include "azure/core/platform.hpp" |
10 | 20 |
|
11 | 21 | // Private include
|
12 | 22 | #include "curl_connection_pool_private.hpp"
|
|
17 | 27 | #include <poll.h> // for poll()
|
18 | 28 | #include <sys/socket.h> // for socket shutdown
|
19 | 29 | #elif defined(AZ_PLATFORM_WINDOWS)
|
20 |
| -#if !defined(WIN32_LEAN_AND_MEAN) |
21 |
| -#define WIN32_LEAN_AND_MEAN |
22 |
| -#endif |
23 |
| -#if !defined(NOMINMAX) |
24 |
| -#define NOMINMAX |
25 |
| -#endif |
26 | 30 | #include <winsock2.h> // for WSAPoll();
|
27 | 31 | #endif
|
28 | 32 |
|
29 | 33 | #include <algorithm>
|
| 34 | +#include <chrono> |
30 | 35 | #include <string>
|
31 | 36 | #include <thread>
|
32 | 37 |
|
@@ -94,25 +99,33 @@ int pollSocketUntilEventOrTimeout(
|
94 | 99 | // we use 1 as arg.
|
95 | 100 |
|
96 | 101 | // Cancelation is possible by calling poll() with small time intervals instead of using the
|
97 |
| - // requested timeout. Default interval for calling poll() is 1 sec whenever arg timeout is |
98 |
| - // greater than 1 sec. Otherwise the interval is set to timeout |
99 |
| - long interval = 1000; // 1 second |
100 |
| - if (timeout < interval) |
101 |
| - { |
102 |
| - interval = timeout; |
103 |
| - } |
| 102 | + // requested timeout. The polling interval is 1 second. |
| 103 | + static constexpr std::chrono::milliseconds pollInterval(1000); // 1 second |
104 | 104 | int result = 0;
|
105 |
| - for (long counter = 0; counter < timeout && result == 0; counter = counter + interval) |
| 105 | + auto now = std::chrono::steady_clock::now(); |
| 106 | + auto deadline = now + std::chrono::milliseconds(timeout); |
| 107 | + while (now < deadline) |
106 | 108 | {
|
107 | 109 | // check cancelation
|
108 | 110 | context.ThrowIfCancelled();
|
| 111 | + std::chrono::milliseconds pollTimeout = std::min( |
| 112 | + poll_interval, std::chrono::duration_cast<std::chrono::milliseconds>(deadline - now)); |
109 | 113 | #if defined(AZ_PLATFORM_POSIX)
|
110 |
| - result = poll(&poller, 1, interval); |
| 114 | + result = poll(&poller, 1, poll_timeout.count()); |
| 115 | + if (result < 0 && EINTR == errno) |
| 116 | + { |
| 117 | + continue; |
| 118 | + } |
111 | 119 | #elif defined(AZ_PLATFORM_WINDOWS)
|
112 |
| - result = WSAPoll(&poller, 1, interval); |
| 120 | + result = WSAPoll(&poller, 1, poll_timeout.count()); |
113 | 121 | #endif
|
| 122 | + if (result != 0) |
| 123 | + { |
| 124 | + return result; |
| 125 | + } |
| 126 | + now = std::chrono::steady_clock::now(); |
114 | 127 | }
|
115 |
| - // result can be either 0 (timeout) or > 1 (socket ready) |
| 128 | + // result can be 0 (timeout), > 0 (socket ready), or < 0 (error) |
116 | 129 | return result;
|
117 | 130 | }
|
118 | 131 |
|
|
0 commit comments