| 282 | } |
| 283 | |
| 284 | ProcessRunner::Results waitForProcessesThreadImpl(HANDLE job, UILocker::Session* ls, |
| 285 | std::atomic<bool>& interrupt) |
| 286 | { |
| 287 | using namespace std::chrono; |
| 288 | |
| 289 | DWORD currentPID = 0; |
| 290 | |
| 291 | // if the interesting process that was found is weak (such as ModOrganizer.exe |
| 292 | // when starting a program from within the Data directory), start with a short |
| 293 | // wait and check for more interesting children |
| 294 | const milliseconds defaultWait(50); |
| 295 | auto wait = defaultWait; |
| 296 | |
| 297 | while (!interrupt) { |
| 298 | auto ip = getInterestingProcess(job); |
| 299 | if (!ip.handle) { |
| 300 | // nothing to wait on |
| 301 | return ProcessRunner::Completed; |
| 302 | } |
| 303 | |
| 304 | // update the lock widget; the session can be null when running shortcuts |
| 305 | // with locking disabled |
| 306 | if (ls) { |
| 307 | ls->setInfo(ip.p.pid(), ip.p.name()); |
| 308 | } |
| 309 | |
| 310 | if (ip.p.pid() != currentPID) { |
| 311 | // log any change in the process being waited for |
| 312 | currentPID = ip.p.pid(); |
| 313 | |
| 314 | log::debug("waiting for completion on {} ({}), {} interest", ip.p.name(), |
| 315 | ip.p.pid(), toString(ip.interest)); |
| 316 | } |
| 317 | |
| 318 | if (ip.interest == Interest::Strong) { |
| 319 | // don't bother with short wait, this is a good process to wait for |
| 320 | wait = Infinite; |
| 321 | } |
| 322 | |
| 323 | const auto r = timedWait(ip.handle.get(), ip.p.pid(), ls, wait, interrupt); |
| 324 | if (r) { |
| 325 | if (*r == ProcessRunner::Results::Completed) { |
| 326 | // process completed, check another one, reset the wait time to find |
| 327 | // interesting processes |
| 328 | wait = defaultWait; |
| 329 | } else if (*r != ProcessRunner::Results::Running) { |
| 330 | // something's wrong, or the user unlocked the ui |
| 331 | return *r; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | // exponentially increase the wait time between checks for interesting |
| 336 | // processes |
| 337 | wait = std::min(wait * 2, milliseconds(2000)); |
| 338 | } |
| 339 | |
| 340 | log::debug("waiting for processes interrupted"); |
| 341 | return ProcessRunner::ForceUnlocked; |
no test coverage detected