Skip to content
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

zloop gets confused if you create timer with same arg as expired timer #114

Closed
hintjens opened this issue Jan 14, 2013 · 4 comments
Closed

Comments

@hintjens
Copy link
Member

Problem: if a timer expires (either by default, or by calling zloop_timer_end(), and you add a new timer with the same argument, zloop will destroy the new timer at the same time as it destroys the expired one.

Solution: when reaping zombie timers, only reap the first one. Secondly, add new timers to end of timer list, not start.

@hintjens
Copy link
Member Author

Test case:

/*
This test exposes a problem with timer handling in zloop whereby
an attempt to replace an old timer with a new one in a socket
event handler does not succeed.

The test below initialises a timer which should be replaced (before
it expired) when the reactor calls s_socket_event.

However, what happens instead is that the new timer, though
added, never fires.

The problem does not occur if the original timer is not deleted,
in which case, both timers fire at the correct time.

Compile: gcc -o timer timer.c -I/usr/local/include -lczmq -lzmq

*/

#include "czmq.h"

static int
s_fire_timer (zloop_t *loop, zmq_pollitem_t *item, void *arg)
{
    printf ("Timer %p fired!\n", arg);
    return 0;
}

static int
s_socket_event (zloop_t *loop, zmq_pollitem_t *item, void *arg)
{
    zmsg_t *msg = zmsg_recv (item->socket);
    zmsg_destroy (&msg);
    printf ("Replacing timer with arg %p\n", item->socket);
    zloop_timer_end (loop, item->socket);

    // Adding a new timer with the same arg as the old one.
    // This will never fire!
    zloop_timer (loop, 1000, 1, s_fire_timer, item->socket);
    return 0;
}

int
zloop_test (bool verbose)
{
    int rc = 0;

    zctx_t *ctx = zctx_new ();
    assert (ctx);

    void *output = zsocket_new (ctx, ZMQ_PAIR);
    assert (output);
    rc = zsocket_bind (output, "inproc://timer.test");
    assert (rc == 0);
    void *input = zsocket_new (ctx, ZMQ_PAIR);
    assert (input);

    rc = zsocket_connect (input, "inproc://timer.test");
    assert (rc == 0);

    zloop_t *loop = zloop_new ();

    assert (loop);
    zloop_set_verbose (loop, verbose);

    //  Create a timer which we're going to *try* to replace
    // in the socket handler... (but it won't get replaced,
    // and will fire eventually!)
    printf ("Creating timer with arg %p\n", input);
    zloop_timer (loop, 5000, 1, s_fire_timer, input);

    zmq_pollitem_t poll_input = { input, 0, ZMQ_POLLIN };
    rc = zloop_poller (loop, &poll_input, s_socket_event, input);
    assert (rc == 0);

    // Send a message to trigger the handler:
    zstr_send (output, "Replace timer!");
    zloop_start (loop);
    zloop_destroy (&loop);
    assert (loop == NULL);

    zctx_destroy (&ctx);
    return 0;
}


int main( void )
{
    return zloop_test (true);
}

hintjens added a commit to hintjens/czmq that referenced this issue Feb 22, 2013
felipecruz pushed a commit that referenced this issue Feb 23, 2013
@ghost
Copy link

ghost commented Nov 15, 2013

If this was fixed in 95381bf shouldn't this be closed?

@hintjens
Copy link
Member Author

@shancat, welcome to the CZMQ maintainers' group :-) Feel welcome to merge pull requests, close issues, and invite others to the group. This is our process: http://rfc.zeromq.org/spec:22

@ghost
Copy link

ghost commented Nov 15, 2013

Wow thanks! Just happy to help :) I'll be sure to read that document
again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant