[zeromq-dev] Bug found: lost message due to EINTR
sven.koebnick at t-online.de
sven.koebnick at t-online.de
Fri Jan 9 10:05:28 CET 2015
Sorry for spamming with the third mail today ...
I had a look into
your implementation of zmsg_send() and there indeed is alogical bug:
sorry for sending the third mail today ...
I had a look into your
implementation of zmsg_send() and indeed found a logical bug.
The
following code assures, that the MESSAGE GETS DESTROYED ALLWAYS, even if
an error occurred in some frame
zmsg_send (zmsg_t **self_p, void
*dest) {
assert (self_p);
assert (dest);
zmsg_t *self = *self_p;
int
rc = 0;
void *handle = zsock_resolve (dest);
if (self) {
assert
(zmsg_is (self));
zframe_t *frame = (zframe_t *) zlist_pop
(self->frames);
while (frame) {
rc = zframe_send (&frame, handle,
zlist_size (self->frames) ? ZFRAME_MORE : 0);
IF (RC != 0)
BREAK;
frame = (zframe_t *) zlist_pop (self->frames);
}
ZMSG_DESTROY (SELF_P);
}
return rc;
}
Am 2015-01-09 09:41, schrieb
sven.koebnick at t-online.de:
> another related thing buthers me in this
context:
>
> When zmsg_send() indeed returns with rc==-1 and a NULLed
message (data is definitely lost) I have a chance to check for this lost
message (simply asserting on rc==-1 && message==NULL).
>
> BUT (!!)
what is with zmsg_recv() ? Situation: I successfully zmsg_send() a
message and is is delivered by ZMQ to the target (still inside ZMQ).
When the same error occurs in the applications zmsg_recv() call, will
the message be returned in the next call to zmsg_recv() or is is lost in
this case also. Here, I do not have any chance to work with a copy as
would be possible in the sending example below.
>
> This question
destroys the first idea of holding a copy before sending. Indeed, I
tryed, but zmsg_dup() destroyes routing information in the message, so
it gets lost(silently) in transport failing to be adressed. Does
zmq_msg_copy() work "better" and also copies the rotuing info?
>
> As
an info: the EINTR thingy happens in Suse Linux on 32 and 64 bit using
ZMQ4 (in any version) while debuging with Eclipse/gdb. I happens VERY
often when breakpoints are triggered, but also (rarely) when the
application is just running under gdb without any suspends due to
breakpoints (breakpoints existing, but not hit).
>
> The system when
pretty well for 2 years (!!!) under ZMQ2 and I have this problem only in
ZMQ4 ... there has never been an EINTR under ZMQ2, so my code had to be
heavily modified with loops for "temporary failures" with errno== EINTR
or EAGAIN.
>
> ^5
>
> Am 2015-01-09 08:30, schrieb
sven.koebnick at t-online.de:
>
>> Hi * !
>>
>> I recently switched
from ZMQ2 (pretty old) to ZMQ 4 and since then have some problems in
debugging with EINTR.
>>
>> Following code:
>>
>> do {
>> rc =
zmsg_send (&zrep, clsocket_);
>> if (rc<0) {
>> if (errno == EINTR ||
errno == EAGAIN) {
>> logWarn("temporary failure in zmq send() ... will
be tried again.");
>> } else {
>> logFatal("hard error in sending zmq
... manually destroying message ... it will be lost");
>>
zmsg_destroy(&zrep);
>> }
>> if (zrep) {
>> logWarn("sending of reply
msg returned rc("<<rc<<"), zmq_errno("<<zmq_errno()<<")
"<<zmq_strerror(zmq_errno()));
>> logWarn("but message is still existent
... retrying");
>> } else {
>> logError("sending of reply msg returned
rc("<<rc<<"), zmq_errno("<<zmq_errno()<<")
"<<zmq_strerror(zmq_errno()));
>> logFatal("message nulled anyway by zmq
... seems lost ...");
>> }
>> }
>> } while (zrep); // repeat until
message is gone
>>
>> This snippet usualy works, but sometimes I get
the warning of EINTR. No problem, I thought, but despite returning an
error (rc==-1, errno==EINTR) the message pointer is NULLed, so I cannot
resend the message.
>>
>> The Logs prove, that indeed the message is
NOT sent, and for resending I'd need a copy ... what am I doing wrong?
>>
>> ^5
>>
>> sven
>>
>>
_______________________________________________
>> zeromq-dev mailing
list
>> zeromq-dev at lists.zeromq.org
>>
http://lists.zeromq.org/mailman/listinfo/zeromq-dev [1]
>
>
_______________________________________________
> zeromq-dev mailing
list
> zeromq-dev at lists.zeromq.org
>
http://lists.zeromq.org/mailman/listinfo/zeromq-dev [1]
zmsg_send
(zmsg_t **self_p, void *dest)
{
assert (self_p);
assert
(dest);
zmsg_t *self = *self_p;
int rc = 0;
void *handle =
zsock_resolve (dest);
if (self) {
assert (zmsg_is (self));
zframe_t *frame = (zframe_t *) zlist_pop (self->frames);
while
(frame) {
rc = zframe_send (&frame, handle,
zlist_size
(self->frames) ? ZFRAME_MORE : 0);
if (rc != 0)
break;
frame
= (zframe_t *) zlist_pop (self->frames);
}
zmsg_destroy
(self_p);
}
return rc;
}
Links:
------
[1]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20150109/cc0b0519/attachment.htm>
More information about the zeromq-dev
mailing list