none
WCF thread pool leak with native thread_local shared_ptr variable RRS feed

  • Question

  • Hi,

    We have a memory leak with one of our servers. Here is
    a simplification of our situation. We have this server using WCF to
    manage requests. In one of our services we use a class in c++/CLI that in turn
    use a native class. In this native class, we have a thread_local variable
    that is a shared_ptr.

    When the application ends and the treads
    are stopped, the objects contained in the shared_ptr are not
    destroyed.

    Note: The objects contained in the tread_local
    shared_ptr variable are destroyed when the threads are stopped while
    the server is running. For example, if we call our service a couple of time,
    after a while some threads (maybe all created by WCF thread pool except one)
    are stopped and then our native objects are destroyed. But when the server
    stops, in the debugger, we see that all the threads are stopped but the
    destructor of our native class is not called.

    Note2 : If we use a static shared_ptr variable instead
    of a thread_local shared_ptr everything is fine.

    Any ideas why? Is it a bug of how WCF terminate its
    threads? Have we forgotten to do something?

    We have a example on github that we used to reproduce
    the problem, I put some parts of the code at the end of this question

    In this example, we have a server that implements the
    DoWork and StopServer services.

    The DoWork service create a clrnative2::CLRClass
    which call a native function that we called fnnative2 which create a
    thread_local shared_ptr of Cnative2, a native class. The Cnative2 class do
    nothing except a printf in its constructor and destructor for debug purpose.

    Like I said, when we run the server in a cmd and that
    we call the DoWork service (example via Client test WCF), in the output, we see
    the construction of our objects and we don't see its destruction when we
    call the StopServer service and that server stop.

    Edit: The same problem occurs even if there is no dynamic allocation and no use of shared_ptr.

    Thank you for your input.

    JM

    namespace WCFServer 
    8    { 
    9    class Program 
    10       { 
    11       static void Main(string[] args) 
    12          { 
    14          System.ServiceModel.ServiceHost host = 
    15             new System.ServiceModel.ServiceHost(typeof(WCFServer.Service)/*, 
    16             new Uri[] { new Uri("http://localhost:8080/LeakingService")}*/); 
    18          host.Open(); 
    19          System.Console.WriteLine("Server listening"); 
    20          Service.s_ev.WaitOne(); 
    21          host.Close(); 
    23          System.Console.WriteLine("Server closed"); 
    24          } 
    25       } 
    26    } 
    9 namespace WCFServer 
    10    { 
    12    public class Service : IService 
    13       { 
    14       public void DoWork() 
    15          { 
    16          clrnative2.CLRClass myObject = new clrnative2.CLRClass(); 
    17          System.Console.Out.WriteLine("WORKING...."); 
    19          } 
    21       public void StopServer() 
    22          { 
    23          s_ev.Set(); 
    24          } 
    27       public static System.Threading.ManualResetEvent s_ev = new System.Threading.ManualResetEvent(false); 
    28       } 
    29    } 
    8 clrnative2::CLRClass::CLRClass() 
    9 { 
    10  fnnative2(); 
    11} 
    12 NATIVE2_API int fnnative2(void) 
    13 { 
    14    thread_local std::shared_ptr<Cnative2> leak(new Cnative2()); 
    16    return 42; 
    17 } 
    23 Cnative2::Cnative2() 
    24    { 
    25    printf("CUNSTRUCTOR tid=%d", GetCurrentThreadId()); 
    26    } 
    29 Cnative2::~Cnative2() 
    30    { 
    31    printf("DESTRUCTOR tid=%d", GetCurrentThreadId()); 
    32    } 





    • Edited by JMRivest Monday, February 12, 2018 7:29 PM
    Monday, February 12, 2018 2:25 PM

All replies

  • Hi JMRivest,

    I am not familiar with C++, please feel free to let me know if there is something wrong in my post related with C++.

    To identity whether your issue is related with C++ implement or WCF Service, if you create a new Winform and call code below from button click by loop, will the application release shared_ptr?

    clrnative2.CLRClass myObject = new clrnative2.CLRClass(); 
    System.Console.Out.WriteLine("WORKING...."); 

    Could you add release method in C++ to release shared_ptr? After finishing calling CLRCLass, release the shared_ptr by this code.

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, February 13, 2018 4:48 AM
  • Hi,

    I try with a simple thread like this

    static void Main(string[] args)
    {
       var th = new Thread(ExecuteInForeground);
       th.Start();
       th.Join();
    }
    
    
    private static void ExecuteInForeground()
    {
       clrnative2.CLRClass myObject = new clrnative2.CLRClass();
       Thread.Sleep(15000);
    }

    After the join,  the native object is destroyed.

    JMR

    Monday, February 19, 2018 5:57 PM
  • Hi JMRivest,

    For your code in WCF, you did not implement Thread, will it work if you try code below?

     public void DoWork() 
              {
       var th = new Thread(ExecuteInForeground);
       th.Start();
       th.Join();           
              } 
    private static void ExecuteInForeground()
    {
       clrnative2.CLRClass myObject = new clrnative2.CLRClass();
       Thread.Sleep(15000);
    }

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, February 22, 2018 3:12 AM