Uploaded image for project: 'Thrift'
  1. Thrift
  2. THRIFT-4449

C# - TNamedPipeServerTransport.AcceptImpl can block indefinitely if TNamedPipeServerTransport.Close is called too quickly

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 0.9.3, 0.11.0
    • Fix Version/s: None
    • Component/s: C# - Library
    • Labels:
    • Environment:

      Windows 10.0.16299 64bit

      Description

      What we observed is, when using the C# implementation TNamedPipeServerTransport along with TSimpleServer, if you call TSimpleServer.Stop too quickly after TSimpleServer.Serve, the call to evt.WaitOne in TNamedPipeServerTransport.AcceptImpl will block indefinitely because the lambda passed into stream.BeginWaitForConnection is never executed and evt.Set will never get called. We saw this in 0.9.3 but it's suspected to be in 0.11.0 as well.

      // in server wrapper class MyServer
      lock (this.serverLock)
      {
          this.serverThread = new Thread(() =>
          {
              var processor = new MyProcessor();
              var transport = new TNamedPipeServerTransport("MyPipeName");
              var svr = new TSimpleServer(processor, transport);
              lock (this.serverLock)
              {
                  this.server = svr;
              }
      
              svr.Serve(); // This sometimes will not return
          })
          {
              IsBackground = true
          };
      
          this.serverThread.Start();
      }
      
      // server wrapper class MyServer
      public void Dispose()
      {
          this.Dispose(true);
      }
      
      protected virtual void Dispose(bool disposing)
      {
          lock (this.serverLock)
          {
              try
              {
                  if (this.server != null)
                  {
                      this.server.Stop();
                  }
      
                  if (this.serverThread != null)
                  {
                      this.serverThread.Join(); // This will wait indefinitely waiting for Serve to complete
                  }
              }
              finally
              {
                  this.server = null;
                  this.serverThread = null;
              }
          }
      }
      
      // test code
      for (int i = 0; i < 100; ++i)
      {
          using (var server = new MyServer())
          {
              server.Start();
          }
      }
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              boxcppguy boxcppguy
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: