Skip to content

Fix infinite loop in doStopApplication() on Windows service stop#610

Draft
Copilot wants to merge 15 commits intomasterfrom
copilot/fix-dostopapplication-infinite-loop
Draft

Fix infinite loop in doStopApplication() on Windows service stop#610
Copilot wants to merge 15 commits intomasterfrom
copilot/fix-dostopapplication-infinite-loop

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

  • Add missing nTries--; decrement in doStopApplication() while loop in service.c
  • Add copyright notice "Portions copyright 2026 3A Systems, LLC" to changed file service.c
  • Merge copilot/add-windows-native-executables (Windows native executables build steps in .github/workflows/build.yml)
Original prompt

Bug

In opendj-server-legacy/src/build-tools/windows/service.c, the doStopApplication() function has a critical bug: the nTries counter is never decremented in the while loop that checks whether the server has stopped. This causes the loop to run infinitely if the server doesn't release its lock file quickly, which leads to the unpredictable start/stop behavior described in issue #72.

Root Cause

In doStopApplication() (line 678), the while loop checks nTries > 0 but never decrements nTries:

      while ((nTries > 0) && running)
      {
        if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK)
        {
          break;
        }
        if (running)
        {
          Sleep(2000);
        }
      }

Compare with the correct implementation in doStartApplication() (line 607-620) which properly decrements:

      while ((nTries > 0) && !running)
      {
        nTries--;    // <-- This is present in doStartApplication but MISSING in doStopApplication
        if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK)
        {
          break;
        }
        ...
      }

Fix Required

Add nTries--; as the first statement inside the while loop in doStopApplication(), right after the opening brace of the while loop on line 679 (between lines 679 and 680), so it matches the pattern used in doStartApplication().

The file is: opendj-server-legacy/src/build-tools/windows/service.c
BlobSha: 0f9f6e0fc0d849157a485f6189518dd70858df7f

The fix is a single line addition. Change the while loop (around line 678) from:

      while ((nTries > 0) && running)
      {
        if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK)

to:

      while ((nTries > 0) && running)
      {
        nTries--;
        if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK)

This ensures the stop polling loop will eventually time out (after ~23 seconds: 3s initial sleep + 10 tries × 2s) rather than hanging indefinitely, which fixes the Windows service stop behavior described in issue #72.

Refs: #72

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: проанализируй

Assistant:

Let me analyze this issue and look at the relevant code in the repository.

Assistant: Вот детальный анализ issue #72"Start-DS and Stop-DS have unpredictable behaviours" на основе исходного кода.


🔍 Корневые причины проблемы

Проанализировав код, я выявил несколько ключевых багов и архитектурных проблем:


1. 🐛 Баг: nTries не декрементируется в doStopApplication() (service.c)

Это критический баг. В функции doStopApplication() в файле service.c:

      int nTries = 10;
      BOOL running = TRUE;

      Sleep(3000);
      while ((nTries > 0) && running)
      {
        if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK)
        {
          break;
        }
        if (running)
        {
          Sleep(2000);
        }
      }

Проблема: Переменная nTries никогда не уменьшается (nTries-- отсутствует). Сравните с аналогичным циклом в doStartApplication(), где nTries-- присутствует:

      while ((nTries > 0) && !running)
      {
        nTries--;  // <--- ЕСТЬ декремент
        if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK)
        {
          break;
        }
        ...
      }

Следствие: Если сервер не останавливается быстро, цикл в doStopApplication() становится бесконечным (пока isServerRunning не вернёт ошибку), что может привести к зависанию Windows-сервиса на этапе STOP_PENDING.


2. 🐛 Ложный exit code 0 у stop-ds.bat

В stop-ds.bat при пути :stopAsWindowsService:

:stopAsWindowsService
echo %SCRIPT%: stop as windows service >> %LOG%
"%OPENDJ_JAVA_BIN%" -client org.opends.server.tools.StopWindowsService
goto end

Проблема: После вызова StopWindowsService скрипт безусловно переходит к :end, не проверяя %errorlevel%. Это значит, что даже если StopWindowsService вернул ошибку, батник завершится с кодом 0. Пользователь видит успешное завершение, хотя сервер ещё работает.


3. 🐛 StopWindowsService.java считает ...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Fix infinite loop in doStopApplication function Fix infinite loop in doStopApplication() on Windows service stop Mar 31, 2026
Copilot AI requested a review from vharseko March 31, 2026 17:06
Copilot AI and others added 5 commits March 31, 2026 19:22
…429e1a9-dbd5-4b36-b891-14c7551bd9c5' into copilot/add-windows-native-executables

# Conflicts:
#	.github/workflows/build.yml

Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
Added git status command to the build process.
@vharseko
Copy link
Copy Markdown
Member

vharseko commented Apr 1, 2026

@copilot merge copilot/add-windows-native-executables

…ub.com/OpenIdentityPlatform/OpenDJ into copilot/fix-dostopapplication-infinite-loop

Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 1, 2026

@copilot merge copilot/add-windows-native-executables

Merged copilot/add-windows-native-executables into this branch (commit adab679).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Start-DS and Stop-DS have unpredictable behaviours

2 participants