Skip to content

Improve ANCM file watcher thread management #49696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

adityamandaleeka
Copy link
Member

I'm trying to get rid of TerminateThread usage in ANCM and decided to tackle the file watcher thread first. This change includes various improvements to the file watcher thread management and shutdown mechanisms.

  • Creation of a new shutdown event m_pShutdownEvent that provides a more explicit and straightforward way to signal the thread to exit.
  • Refactoring of FILE_WATCHER::ChangeNotificationThread to use WaitForMultipleObjects to wait on either the completion port or the new shutdown event, removing the need for the FILE_WATCHER_SHUTDOWN_KEY mechanism.
  • Simplification of FILE_WATCHER::WaitForMonitor by removing calls to GetExitCodeThread and TerminateThread, relying on WaitForSingleObject to handle thread state checking and waiting.
  • Replacement of the volatile BOOL m_fThreadExit with a std::atomic<bool>
  • Other minor improvements

Contributes towards #45066

@ghost ghost added the area-runtime label Jul 28, 2023
@adityamandaleeka adityamandaleeka added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions feature-iis Includes: IIS, ANCM and removed area-runtime labels Jul 28, 2023

while (!m_fThreadExit && dwRetryCounter > 0)
while (!m_fThreadExit && dwRetryCounter-- > 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the thread doesn't exit after the loop completes?

And, should we log in that case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, done.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option if we want to de-risk this in .NET 8 is to enable the termination behavior behind a flag.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the thread doing that could be "bad" if it's still running?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offline discussion: The thread is holding onto state that can have undefined behavior if accessed when the class is destructed. e.g. FILE_WATCHER* and the m_pShutdownEvent and m_hCompletionPort events.

Which brings up another thing, those events are never closed via CloseHandle it looks like.

else
{
// Wait for the thread to exit.
WaitForSingleObject(m_hChangeNotificationThread, INFINITE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WaitForSingleObject(m_hChangeNotificationThread, INFINITE);
LOG_INFO(L"Waiting for File watcher thread to exit.");
WaitForSingleObject(m_hChangeNotificationThread, INFINITE);

So we know if it's hanging. The thread itself logs when it exits.

Copy link
Member

@BrennanConroy BrennanConroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a log should be added

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions feature-iis Includes: IIS, ANCM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants