Can't completely shutdown libCa and libCom

Bug #1879532 reported by Andrew Johnson
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
Confirmed
Wishlist
Unassigned

Bug Description

Most recently, Carsten Winkler reported in https://epics.anl.gov/tech-talk/2020/msg00946.php

    For a project I need to load and unload the Channel Access context in a
    shared library. Loading is no problem but unloading. It always fails
    during ca_context_destroy() function.

This problem has been reported and discussed previously, see https://epics.anl.gov/tech-talk/2017/msg00371.php and https://epics.anl.gov/tech-talk/2004/msg00743.php thus it is a known issue which would probably require significant work to fix.

This bug report is a place-holder for any work towards making it possible to completely shut down all libCom background threads and releasing the resources allocated by those subsystems.

Revision history for this message
Peter Heesterman (pheest) wrote :

I am able to reproduce the issue, using the code that Carsten posted.

On deleting the timer queue, the thread destructor calls epicsThreadMustJoin.
This gets stuck forever at line 642 in osdThread.c :

if(epicsThreadGetIdSelf() != id) {
        DWORD status = WaitForSingleObject(pParmWIN32->handle, INFINITE);

Revision history for this message
Freddie Akeroyd (freddie-akeroyd) wrote :

The thread it is waiting on seems to be stuck in "common_end_thread" in ucrtbase, calling ca_context_destroy() from main() with no DLL involved works correctly.

There are various guidelines on what you should and should not do from inside a dllMain() function
https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
Unfortunately using a file level static class does not help as the same rules would appear to apply

"If your DLL is linked with the C run-time library (CRT), the entry point provided by the CRT calls the constructors and destructors for global and static C++ objects. Therefore, these restrictions for DllMain also apply to constructors and destructors and any code that is called from them."

(from https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain )

Revision history for this message
Peter Heesterman (pheest) wrote :

See https://stackoverflow.com/questions/35828004/waitforsingleobject-for-thread-object-does-not-work-in-dll-unload

I have implemented a solution by creating a function within the myCaLab DLL which in turn ca_task_exit (or ca_context_destroy), and which called from the main application.
This causes it to exit normally.

Is this a solution that meets your needs?

Revision history for this message
Andrew Johnson (anj) wrote :

I don't know if Carsten will see messages posted here or not, so please make sure you communicate with him by direct email as well. He did say he was going to be on vacation for a few days though.

Revision history for this message
Freddie Akeroyd (freddie-akeroyd) wrote :

Hi @pheest, interesting article - did you implement the two part DLL solution mentioned?

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.