dingmaotu / mql-zmq

ZMQ binding for the MQL language (both 32bit MT4 and 64bit MT5)
Apache License 2.0
553 stars 301 forks source link

Raise error in Socket::poll() as polling socket and monitor at the same time #14

Closed janckerchen closed 5 years ago

janckerchen commented 6 years ago

I need listen the events from the socket, so I was polling socket and monitor at the same time in Update().

I dig the error step by step and provide test sourcecode

  1. if I just polling socket, it works. so Socket::poll() is ok.

test_zmq_poll_socket.mq5

  void ZmqServer() {
    sock_.fillPollItem(polls_[0], ZMQ_POLLIN);
  }
  void Update() {

    Socket::poll(polls_, 0); <-- just polling sokect

    if (polls_[0].hasInput())
      recieve_zmq_message();  

  }
  1. if I just polling monitor, it works too. so monitor socket is ok

test_zmq_poll_monitor.mq5


void ZmqServer() {
monitor_.fillPollItem(polls_[0], ZMQ_POLLIN);
}
void Update() {
Socket::poll(polls_, 0);  <-- just polling monitor

if (polls_[0].hasInput())      
  dispatch_monitor_events();

}


3. if I polling socket and monitor at the same time,  EA failed to start up with error like screenshot.

![screenshot of parallels desktop 2017 12 11 14 03](https://user-images.githubusercontent.com/68181/33818397-9998202a-de7f-11e7-8e15-915538644521.png)

> test_zmq_poll_monitor_and_socket.mq5
```c++
  void ZmqServer() {
    sock_.fillPollItem(polls_[0], ZMQ_POLLIN);
    monitor_.fillPollItem(polls_[1], ZMQ_POLLIN);
  }
  void Update() {

    Socket::poll(polls_, 0);  <-- polling socket and monitor

     if (polls_[0].hasInput())
       recieve_zmq_message();  

     if (polls_[1].hasInput())      
      dispatch_monitor_events();

  }

all test code:

test_sourcecode.zip

It confused me for a while, need help!

dingmaotu commented 6 years ago

Hi, I can confirm the crash but this is a strange problem as I don't see any potential error in the code. It may be a bug of ZMQ. I would suggest you try to write the same program in C/C++ and see if it still crashes. If it is the case, you should resort to ZMQ project and you may have a better chance to get your problem solved.

feng-ye commented 6 years ago

It is padding problem. The size of zmq_pollitem_t in C side is 24 bytes(win64).

Adding 4 bytes padding to PollItem works for me.

struct PollItem
  {
   intptr_t          socket;
   uintptr_t         fd;
   short             events;
   short             revents;
   char              padding[4];

   bool              hasInput() const {return(revents&ZMQ_POLLIN)!=0;}
   bool              hasOutput() const {return(revents&ZMQ_POLLOUT)!=0;}
  };