From e775fe8f306e7ae1093a98bef92d0548d943e5eb Mon Sep 17 00:00:00 2001 From: Jasem Mutlaq Date: Mon, 23 Dec 2024 12:59:32 +0300 Subject: [PATCH] Protect against premature timeouts --- indi-gphoto/gphoto_driver.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/indi-gphoto/gphoto_driver.cpp b/indi-gphoto/gphoto_driver.cpp index 74080b7a2..3f98f08c2 100644 --- a/indi-gphoto/gphoto_driver.cpp +++ b/indi-gphoto/gphoto_driver.cpp @@ -1387,7 +1387,9 @@ int gphoto_read_exposure_fd(gphoto_driver *gphoto, int fd) gphoto->command = 0; uint32_t waitMS = gphoto->download_timeout * 1000; bool downloadComplete = false; - DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "BULB Mode: Waiting for event for %d seconds.", gphoto->download_timeout); + struct timeval start_time; + gettimeofday(&start_time, nullptr); + DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "BULB Mode: Waiting for event for %d seconds (waitMS: %d).", gphoto->download_timeout, waitMS); while (1) { @@ -1413,19 +1415,38 @@ int gphoto_read_exposure_fd(gphoto_driver *gphoto, int fd) fn = static_cast(data); if (gphoto->handle_sdcard_image != IGNORE_IMAGE) download_image(gphoto, fn, fd); - waitMS = 100; downloadComplete = true; + // Wait 1 second for GP_EVENT_CAPTURE_COMPLETE + // If that times out, we already marked downloadComplete as true so we will exist gracefully. + waitMS = 1000; break; case GP_EVENT_UNKNOWN: //DEBUGDEVICE(device, INDI::Logger::DBG_DEBUG, "Unknown event."); break; case GP_EVENT_TIMEOUT: + // If already downloaded, then return immediately. if (downloadComplete) { pthread_mutex_unlock(&gphoto->mutex); return GP_OK; } - DEBUGDEVICE(device, INDI::Logger::DBG_DEBUG, "Event timed out."); + + // Check how much time actually elapsed. + struct timeval current_time; + gettimeofday(¤t_time, nullptr); + uint32_t elapsed = ((current_time.tv_sec - start_time.tv_sec) * 1000 + + (current_time.tv_usec - start_time.tv_usec) / 1000); + + // If we haven't waited the full timeout period yet, continue waiting + if (elapsed < waitMS) + { + DEBUGDEVICE(device, INDI::Logger::DBG_DEBUG, "Timeout was premature, continuing to wait..."); + usleep(100000); + break; + } + + // Give up as we timed out. + DEBUGFDEVICE(device, INDI::Logger::DBG_DEBUG, "Event timed out after %d ms (elapsed: %d ms).", waitMS, elapsed); pthread_mutex_unlock(&gphoto->mutex); return -1; break;