[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