zeromq / clrzmq4

ZeroMQ C# namespace (.NET and mono, Windows, Linux and MacOSX, x86 and amd64)
GNU Lesser General Public License v3.0
241 stars 112 forks source link

NullReferenceException from ZeroMQ.ZPollItems.PollIn in ROUTER<-->DEALER communication #210

Open AntiTenzor opened 3 years ago

AntiTenzor commented 3 years ago

I'm trying to have fun with ROUTER<-->DEALER scenario.

To avoid blocking reads I try to poll ROUTER socket before reading data from it. But my router becomes crazy from time to time. I do not know at the moment how to reproduce this situation in a toy project.

Environment:

Idea of what I do:

// Constructor of a class ZRouter
public ZRouter()
        {
            clrZmqContext = ZContext.Current;

            mainThread = new Thread(mainThreadImpl);

            clrZmqPollIn = ZPollItem.CreateReceiver();
            clrZmqRouter = new ZSocket(clrZmqContext, ZSocketType.ROUTER);

            ...
         }

// Later when initialization is done mainThread.Start();

// There is infinite loop in mainThread:

while(true)
{
  if (!clrZmqRouter.PollIn(clrZmqPollIn, out ZMessage incoming, out ZError error, TimeSpan.FromSeconds(0.7)))
  {
      continue;
  }

  string identity = incoming.PopString();
  string msg = incoming.PopString();

  // Further processing
}

// Other threads could send messages from ROUTER to its DEALERS.

The sad part of a story: After some hours of working I start to get a NullReferenceException from the line if (!clrZmqRouter.PollIn(clrZmqPollIn, out ZMessage incoming, out ZError error, TimeSpan.FromSeconds(0.7)))

Here is a stack trace:

System.NullReferenceException: Object reference not set to an instance of an object.
   at ZeroMQ.lib.zmq.zmq_poll(Void* items, Int32 numItems, Int64 timeout)
   at ZeroMQ.ZPollItems.Win32.PollSingle(ZSocket socket, ZPollItem item, ZPoll pollEvents, ZError& error, Nullable`1 timeout) in w:\git\clrzmq4\ZPollItems.Win32.cs:line 79
   at ZeroMQ.ZPollItems.Poll(ZSocket socket, ZPollItem item, ZPoll pollEvents, ZMessage& message, ZError& error, Nullable`1 timeout) in w:\git\clrzmq4\ZPollItems.cs:line 47
   at ZeroMQ.ZPollItems.PollIn(ZSocket socket, ZPollItem item, ZMessage& incoming, ZError& error, Nullable`1 timeout) in w:\git\clrzmq4\ZPollItems.cs:line 32
   at ZRouter.ZRouter.mainThreadImpl() in W:\...\ZRouter\ZRouter.cs:line 185

Is ZSocket thread safe for multithreaded environment? Should I create special ZContext inside mainThread?