| 164 | } |
| 165 | |
| 166 | lword NonblockingSink::TimedFlush(unsigned long maxTime, size_t targetSize) |
| 167 | { |
| 168 | m_blockedBySpeedLimit = false; |
| 169 | |
| 170 | size_t curBufSize = GetCurrentBufferSize(); |
| 171 | if (curBufSize <= targetSize && (targetSize || !EofPending())) |
| 172 | return 0; |
| 173 | |
| 174 | if (!GetMaxBytesPerSecond()) |
| 175 | return DoFlush(maxTime, targetSize); |
| 176 | |
| 177 | bool forever = (maxTime == INFINITE_TIME); |
| 178 | unsigned long timeToGo = maxTime; |
| 179 | Timer timer(Timer::MILLISECONDS, forever); |
| 180 | lword totalFlushed = 0; |
| 181 | |
| 182 | timer.StartTimer(); |
| 183 | |
| 184 | while (true) |
| 185 | { |
| 186 | size_t flushSize = UnsignedMin(curBufSize - targetSize, ComputeCurrentTransceiveLimit()); |
| 187 | if (flushSize || EofPending()) |
| 188 | { |
| 189 | if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); |
| 190 | size_t ret = (size_t)DoFlush(timeToGo, curBufSize - flushSize); |
| 191 | if (ret) |
| 192 | { |
| 193 | NoteTransceive(ret); |
| 194 | curBufSize -= ret; |
| 195 | totalFlushed += ret; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | if (curBufSize <= targetSize && (targetSize || !EofPending())) |
| 200 | break; |
| 201 | |
| 202 | if (!forever) |
| 203 | { |
| 204 | timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); |
| 205 | if (!timeToGo) |
| 206 | break; |
| 207 | } |
| 208 | |
| 209 | double waitTime = TimeToNextTransceive(); |
| 210 | if (!forever && waitTime > timeToGo) |
| 211 | { |
| 212 | m_blockedBySpeedLimit = true; |
| 213 | break; |
| 214 | } |
| 215 | |
| 216 | WaitObjectContainer container; |
| 217 | LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSink::TimedFlush() - speed limit", 0)); |
| 218 | container.Wait((unsigned long)waitTime); |
| 219 | } |
| 220 | |
| 221 | return totalFlushed; |
| 222 | } |
| 223 |
nothing calls this directly
no test coverage detected