-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible inconsistency with xrep_t::current_in, xrep_t::more_in after pipe is terminated #69
Comments
Hi, can you point me to the version of 0MQ you are using, the file and the line? I'll have a look. |
It was master branch at the time I started this issue. More specific: The reader pipe is removed form the inpipes, without updating the current_in member. current_in is initialized here: It is updated when iterating over readers here: http://github.com/zeromq/zeromq2/blob/master/src/xrep.cpp#L211 and here: Now if it is possible that a reader is terminated in the middle of this loop, for example, some other code is called, and the other code cause the reader to close, current_in wil be wrong, as described above. Even if this is not possible now, it may be possible in the future. current_in should be update when a reader is terminated, just like current_out is when a writer is terminated, here: |
I've checked the code and AFAICS the reader cannot be terminated in the middle of the loop. The list of pipes is local to this thread and cannot be modified in the background. |
Ah, but a different thing can happen: Termination of reader can leave current_in pointing past the end of the array and subsequent attempt to recv may thus segfault! |
Fixed in r98fa2fa. Thanks for spotting this! |
This does not fix the inconsistency with more_in, prefetched and prefetched_msg members. Possible issues:
A better fix is to update all members related to reading a message from a reader: prefetched, prefetched_msg and more_in. Something like:
The you invoke this when current reader is changed. |
The point is that reader cannot terminate in the middle of multipart message. Message is delivered either whole or not at all. |
So the reader is responsible for checking xrep state before calling terminated? Where is this enforced? |
Nope. terminate only happens when reader reads the last message (the "delimiter") from the pipe. Pipe writer is responsible for sending only whole messages, so the delimiter may not occur in the middle of the message. If there's half written message and sender wants to send delimiter, it rollbacks the unfinished message from the pipe. |
Ok, maybe some asserts are missing, blowing up if the reader breaks the contract you described. Add above http://github.com/zeromq/zeromq2/blob/master/src/xrep.cpp#L104:
|
Sure. Feel free to send it as a patch to the mailing list. |
I guess we can close this issue. |
Fixes to LIBZMQ-411 ZMQ 2.x compilation problems when building with disabled asserts.
Close pipes for inproc sockets on zmq_disconnect
missing static specifier for file local function
It seems that after a reader invoke xrep_t::terminated() and the pipe is removed from the inpipes vector, current_in is not updated.
If the terminated pipe was the last in the list, the current_in was last index, it will be invalid at this point. The next time xrecv is called, inpipes[current_in] may be out of the vector bounds.
If the terminated pipe was before current_in, and more_in is true, current_in points now to the next pipe, and more_in is invalid.
I did not check that this situation is reproducible.
The text was updated successfully, but these errors were encountered: