mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 15:41:05 +08:00
Merge pull request #1675 from somdoron/Timers
Problem: no way to schedule timers with zmq_poll or zmq_poller
This commit is contained in:
commit
c19470ece1
1
.gitignore
vendored
1
.gitignore
vendored
@ -117,6 +117,7 @@ test_getsockopt_memset
|
|||||||
test_setsockopt
|
test_setsockopt
|
||||||
test_stream_exceeds_buffer
|
test_stream_exceeds_buffer
|
||||||
test_poller
|
test_poller
|
||||||
|
test_timers
|
||||||
tests/test*.log
|
tests/test*.log
|
||||||
tests/test*.trs
|
tests/test*.trs
|
||||||
src/platform.hpp*
|
src/platform.hpp*
|
||||||
|
@ -449,6 +449,7 @@ set(cxx-sources
|
|||||||
zmq_utils.cpp
|
zmq_utils.cpp
|
||||||
decoder_allocators.cpp
|
decoder_allocators.cpp
|
||||||
socket_poller.cpp
|
socket_poller.cpp
|
||||||
|
timers.cpp
|
||||||
config.hpp)
|
config.hpp)
|
||||||
|
|
||||||
set(rc-sources version.rc)
|
set(rc-sources version.rc)
|
||||||
|
@ -179,6 +179,8 @@ src_libzmq_la_SOURCES = \
|
|||||||
src/tcp_listener.hpp \
|
src/tcp_listener.hpp \
|
||||||
src/thread.cpp \
|
src/thread.cpp \
|
||||||
src/thread.hpp \
|
src/thread.hpp \
|
||||||
|
src/timers.cpp \
|
||||||
|
src/timers.hpp \
|
||||||
src/tipc_address.cpp \
|
src/tipc_address.cpp \
|
||||||
src/tipc_address.hpp \
|
src/tipc_address.hpp \
|
||||||
src/tipc_connecter.cpp \
|
src/tipc_connecter.cpp \
|
||||||
@ -376,7 +378,8 @@ test_apps = \
|
|||||||
tests/test_socketopt_hwm \
|
tests/test_socketopt_hwm \
|
||||||
tests/test_heartbeats \
|
tests/test_heartbeats \
|
||||||
tests/test_stream_exceeds_buffer \
|
tests/test_stream_exceeds_buffer \
|
||||||
tests/test_poller
|
tests/test_poller \
|
||||||
|
tests/test_timers
|
||||||
|
|
||||||
tests_test_system_SOURCES = tests/test_system.cpp
|
tests_test_system_SOURCES = tests/test_system.cpp
|
||||||
tests_test_system_LDADD = src/libzmq.la
|
tests_test_system_LDADD = src/libzmq.la
|
||||||
@ -587,6 +590,9 @@ tests_test_stream_exceeds_buffer_LDADD = src/libzmq.la
|
|||||||
tests_test_poller_SOURCES = tests/test_poller.cpp
|
tests_test_poller_SOURCES = tests/test_poller.cpp
|
||||||
tests_test_poller_LDADD = src/libzmq.la
|
tests_test_poller_LDADD = src/libzmq.la
|
||||||
|
|
||||||
|
tests_test_timers_SOURCES = tests/test_timers.cpp
|
||||||
|
tests_test_timers_LDADD = src/libzmq.la
|
||||||
|
|
||||||
|
|
||||||
if !ON_MINGW
|
if !ON_MINGW
|
||||||
if !ON_CYGWIN
|
if !ON_CYGWIN
|
||||||
@ -729,4 +735,3 @@ dist-hook:
|
|||||||
|
|
||||||
maintainer-clean-local:
|
maintainer-clean-local:
|
||||||
-rm -rf $(top_srcdir)/config
|
-rm -rf $(top_srcdir)/config
|
||||||
|
|
||||||
|
@ -451,6 +451,21 @@ ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, int fd, short events);
|
|||||||
ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, int fd);
|
ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, int fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Scheduling timers */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
typedef void (zmq_timer_fn)(int timer_id, void *arg);
|
||||||
|
|
||||||
|
ZMQ_EXPORT void *zmq_timers_new ();
|
||||||
|
ZMQ_EXPORT int zmq_timers_close (void *timers);
|
||||||
|
ZMQ_EXPORT int zmq_timers_add (void *timers, size_t interval, zmq_timer_fn handler, void *arg);
|
||||||
|
ZMQ_EXPORT int zmq_timers_cancel (void *timers, int timer_id);
|
||||||
|
ZMQ_EXPORT int zmq_timers_set_interval (void *timers, int timer_id, size_t interval);
|
||||||
|
ZMQ_EXPORT int zmq_timers_reset (void *timers, int timer_id);
|
||||||
|
ZMQ_EXPORT long zmq_timers_timeout (void *timers);
|
||||||
|
ZMQ_EXPORT int zmq_timers_execute (void *timers);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Message proxying */
|
/* Message proxying */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -542,4 +557,3 @@ ZMQ_EXPORT void zmq_threadclose (void* thread);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
169
src/timers.cpp
Normal file
169
src/timers.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007-2015 Contributors as noted in the AUTHORS file
|
||||||
|
|
||||||
|
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||||
|
|
||||||
|
libzmq is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||||
|
by the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
As a special exception, the Contributors give you permission to link
|
||||||
|
this library with independent modules to produce an executable,
|
||||||
|
regardless of the license terms of these independent modules, and to
|
||||||
|
copy and distribute the resulting executable under terms of your choice,
|
||||||
|
provided that you also meet, for each linked independent module, the
|
||||||
|
terms and conditions of the license of that module. An independent
|
||||||
|
module is a module which is not derived from or based on this library.
|
||||||
|
If you modify this library, you must extend this exception to your
|
||||||
|
version of the library.
|
||||||
|
|
||||||
|
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "timers.hpp"
|
||||||
|
#include "err.hpp"
|
||||||
|
|
||||||
|
zmq::timers_t::timers_t () :
|
||||||
|
tag (0xCAFEDADA),
|
||||||
|
next_timer_id (0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
zmq::timers_t::~timers_t ()
|
||||||
|
{
|
||||||
|
// Mark the timers as dead
|
||||||
|
tag = 0xdeadbeef;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool zmq::timers_t::check_tag ()
|
||||||
|
{
|
||||||
|
return tag == 0xCAFEDADA;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::timers_t::add (size_t interval_, timers_timer_fn handler_, void* arg_)
|
||||||
|
{
|
||||||
|
uint64_t when = clock.now_ms() + interval_;
|
||||||
|
timer_t timer = {++next_timer_id, interval_, handler_, arg_};
|
||||||
|
timers.insert (timersmap_t::value_type (when, timer));
|
||||||
|
|
||||||
|
return timer.timer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::timers_t::cancel (int timer_id_)
|
||||||
|
{
|
||||||
|
cancelled_timers_t::iterator it = cancelled_timers.find (timer_id_);
|
||||||
|
|
||||||
|
if (it != cancelled_timers.end ()) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelled_timers.insert (timer_id_);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::timers_t::set_interval (int timer_id_, size_t interval_)
|
||||||
|
{
|
||||||
|
for (timersmap_t::iterator it = timers.begin (); it != timers.end (); ++it) {
|
||||||
|
if (it->second.timer_id == timer_id_) {
|
||||||
|
timer_t timer = it->second;
|
||||||
|
timer.interval = interval_;
|
||||||
|
uint64_t when = clock.now_ms() + interval_;
|
||||||
|
timers.erase (it);
|
||||||
|
timers.insert (timersmap_t::value_type (when, timer));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::timers_t::reset (int timer_id_) {
|
||||||
|
for (timersmap_t::iterator it = timers.begin (); it != timers.end (); ++it) {
|
||||||
|
if (it->second.timer_id == timer_id_) {
|
||||||
|
timer_t timer = it->second;
|
||||||
|
uint64_t when = clock.now_ms() + timer.interval;
|
||||||
|
timers.erase (it);
|
||||||
|
timers.insert (timersmap_t::value_type (when, timer));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long zmq::timers_t::timeout ()
|
||||||
|
{
|
||||||
|
timersmap_t::iterator it = timers.begin ();
|
||||||
|
|
||||||
|
uint64_t now = clock.now_ms();
|
||||||
|
|
||||||
|
while (it != timers.end ()) {
|
||||||
|
cancelled_timers_t::iterator cancelled_it = cancelled_timers.find (it->second.timer_id);
|
||||||
|
|
||||||
|
// Live timer, lets return the timeout
|
||||||
|
if (cancelled_it == cancelled_timers.end ()) {
|
||||||
|
if (it->first > now)
|
||||||
|
return it->first - now;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's remove it from the begining of the list
|
||||||
|
timersmap_t::iterator old = it;
|
||||||
|
++it;
|
||||||
|
timers.erase (old);
|
||||||
|
cancelled_timers.erase (cancelled_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait forever as no timers are alive
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::timers_t::execute ()
|
||||||
|
{
|
||||||
|
timersmap_t::iterator it = timers.begin ();
|
||||||
|
|
||||||
|
uint64_t now = clock.now_ms();
|
||||||
|
|
||||||
|
while (it != timers.end ()) {
|
||||||
|
cancelled_timers_t::iterator cancelled_it = cancelled_timers.find (it->second.timer_id);
|
||||||
|
|
||||||
|
// Dead timer, lets remove it and continue
|
||||||
|
if (cancelled_it != cancelled_timers.end ()) {
|
||||||
|
timersmap_t::iterator old = it;
|
||||||
|
++it;
|
||||||
|
timers.erase (old);
|
||||||
|
cancelled_timers.erase (cancelled_it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map is ordered, if we have to wait for current timer we can stop.
|
||||||
|
if (it->first > now)
|
||||||
|
break;
|
||||||
|
|
||||||
|
timer_t timer = it->second;
|
||||||
|
|
||||||
|
timer.handler (timer.timer_id, timer.arg);
|
||||||
|
|
||||||
|
timersmap_t::iterator old = it;
|
||||||
|
++it;
|
||||||
|
timers.erase (old);
|
||||||
|
timers.insert (timersmap_t::value_type (now + timer.interval, timer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
108
src/timers.hpp
Normal file
108
src/timers.hpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007-2015 Contributors as noted in the AUTHORS file
|
||||||
|
|
||||||
|
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||||
|
|
||||||
|
libzmq is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||||
|
by the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
As a special exception, the Contributors give you permission to link
|
||||||
|
this library with independent modules to produce an executable,
|
||||||
|
regardless of the license terms of these independent modules, and to
|
||||||
|
copy and distribute the resulting executable under terms of your choice,
|
||||||
|
provided that you also meet, for each linked independent module, the
|
||||||
|
terms and conditions of the license of that module. An independent
|
||||||
|
module is a module which is not derived from or based on this library.
|
||||||
|
If you modify this library, you must extend this exception to your
|
||||||
|
version of the library.
|
||||||
|
|
||||||
|
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ZMQ_TIMERS_HPP_INCLUDED__
|
||||||
|
#define __ZMQ_TIMERS_HPP_INCLUDED__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "clock.hpp"
|
||||||
|
|
||||||
|
namespace zmq
|
||||||
|
{
|
||||||
|
typedef void (timers_timer_fn)(
|
||||||
|
int timer_id, void *arg);
|
||||||
|
|
||||||
|
class timers_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
timers_t ();
|
||||||
|
~timers_t ();
|
||||||
|
|
||||||
|
// Add timer to the set, timer repeats forever, or until cancel is called.
|
||||||
|
// Returns a timer_id that is used to cancel the timer.
|
||||||
|
// Returns -1 if there was an error.
|
||||||
|
int add (size_t interval, timers_timer_fn handler, void* arg);
|
||||||
|
|
||||||
|
// Set the interval of the timer.
|
||||||
|
// This method is slow, cancelling exsting and adding a new timer yield better performance.
|
||||||
|
// Returns 0 on success and -1 on error.
|
||||||
|
int set_interval (int timer_id, size_t interval);
|
||||||
|
|
||||||
|
// Reset the timer.
|
||||||
|
// This method is slow, cancelling exsting and adding a new timer yield better performance.
|
||||||
|
// Returns 0 on success and -1 on error.
|
||||||
|
int reset (int timer_id);
|
||||||
|
|
||||||
|
// Cancel a timer.
|
||||||
|
// Returns 0 on success and -1 on error.
|
||||||
|
int cancel (int timer_id);
|
||||||
|
|
||||||
|
// Returns the time in millisecond until the next timer.
|
||||||
|
// Returns -1 if no timer is due.
|
||||||
|
long timeout ();
|
||||||
|
|
||||||
|
// Execute timers.
|
||||||
|
// Return 0 if all succeed and -1 if error.
|
||||||
|
int execute ();
|
||||||
|
|
||||||
|
// Return false if object is not a timers class.
|
||||||
|
bool check_tag ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Used to check whether the object is a timers class.
|
||||||
|
uint32_t tag;
|
||||||
|
|
||||||
|
int next_timer_id;
|
||||||
|
|
||||||
|
// Clock instance.
|
||||||
|
clock_t clock;
|
||||||
|
|
||||||
|
typedef struct timer_t {
|
||||||
|
int timer_id;
|
||||||
|
size_t interval;
|
||||||
|
timers_timer_fn *handler;
|
||||||
|
void *arg;
|
||||||
|
} timer_t;
|
||||||
|
|
||||||
|
typedef std::multimap <uint64_t, timer_t> timersmap_t;
|
||||||
|
timersmap_t timers;
|
||||||
|
|
||||||
|
typedef std::set<int> cancelled_timers_t;
|
||||||
|
cancelled_timers_t cancelled_timers;
|
||||||
|
|
||||||
|
timers_t (const timers_t&);
|
||||||
|
const timers_t &operator = (const timers_t&);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
81
src/zmq.cpp
81
src/zmq.cpp
@ -77,6 +77,7 @@ struct iovec {
|
|||||||
#include "metadata.hpp"
|
#include "metadata.hpp"
|
||||||
#include "signaler.hpp"
|
#include "signaler.hpp"
|
||||||
#include "socket_poller.hpp"
|
#include "socket_poller.hpp"
|
||||||
|
#include "timers.hpp"
|
||||||
|
|
||||||
#if !defined ZMQ_HAVE_WINDOWS
|
#if !defined ZMQ_HAVE_WINDOWS
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -1175,6 +1176,86 @@ int zmq_poller_wait (void *poller_, zmq_poller_event_t *event, long timeout_)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Timers
|
||||||
|
|
||||||
|
void *zmq_timers_new ()
|
||||||
|
{
|
||||||
|
zmq::timers_t *timers = new (std::nothrow) zmq::timers_t;
|
||||||
|
alloc_assert (timers);
|
||||||
|
return timers;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq_timers_close (void *timers_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete ((zmq::timers_t*)timers_);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq_timers_add (void *timers_, size_t interval_, zmq_timer_fn handler_, void *arg_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((zmq::timers_t*)timers_)->add (interval_, handler_, arg_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq_timers_cancel (void *timers_, int timer_id_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((zmq::timers_t*)timers_)->cancel (timer_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq_timers_set_interval (void *timers_, int timer_id_, size_t interval_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((zmq::timers_t*)timers_)->set_interval (timer_id_, interval_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq_timers_reset (void *timers_, int timer_id_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((zmq::timers_t*)timers_)->reset (timer_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
long zmq_timers_timeout (void *timers_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((zmq::timers_t*)timers_)->timeout ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq_timers_execute (void *timers_)
|
||||||
|
{
|
||||||
|
if (!timers_ || !((zmq::timers_t*)timers_)->check_tag ()) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((zmq::timers_t*)timers_)->execute ();
|
||||||
|
}
|
||||||
|
|
||||||
// The proxy functionality
|
// The proxy functionality
|
||||||
|
|
||||||
int zmq_proxy (void *frontend_, void *backend_, void *capture_)
|
int zmq_proxy (void *frontend_, void *backend_, void *capture_)
|
||||||
|
@ -69,6 +69,7 @@ set(tests
|
|||||||
test_sub_forward_tipc
|
test_sub_forward_tipc
|
||||||
test_xpub_manual
|
test_xpub_manual
|
||||||
test_xpub_welcome_msg
|
test_xpub_welcome_msg
|
||||||
|
test_timers
|
||||||
)
|
)
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
list(APPEND tests
|
list(APPEND tests
|
||||||
|
126
tests/test_timers.cpp
Normal file
126
tests/test_timers.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007-2015 Contributors as noted in the AUTHORS file
|
||||||
|
|
||||||
|
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||||
|
|
||||||
|
libzmq is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||||
|
by the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
As a special exception, the Contributors give you permission to link
|
||||||
|
this library with independent modules to produce an executable,
|
||||||
|
regardless of the license terms of these independent modules, and to
|
||||||
|
copy and distribute the resulting executable under terms of your choice,
|
||||||
|
provided that you also meet, for each linked independent module, the
|
||||||
|
terms and conditions of the license of that module. An independent
|
||||||
|
module is a module which is not derived from or based on this library.
|
||||||
|
If you modify this library, you must extend this exception to your
|
||||||
|
version of the library.
|
||||||
|
|
||||||
|
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "testutil.hpp"
|
||||||
|
#include "../include/zmq_utils.h"
|
||||||
|
|
||||||
|
#if defined ZMQ_HAVE_WINDOWS
|
||||||
|
#include "windows.hpp"
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _sleep (long timeout_)
|
||||||
|
{
|
||||||
|
#if defined ZMQ_HAVE_WINDOWS
|
||||||
|
Sleep (timeout_ > 0 ? timeout_ : INFINITE);
|
||||||
|
#elif defined ZMQ_HAVE_ANDROID
|
||||||
|
usleep (timeout_ * 1000);
|
||||||
|
#else
|
||||||
|
usleep (timeout_ * 1000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void handler (int timer_id, void* arg)
|
||||||
|
{
|
||||||
|
*((bool *)arg) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
setup_test_environment ();
|
||||||
|
|
||||||
|
void* timers = zmq_timers_new ();
|
||||||
|
assert (timers);
|
||||||
|
|
||||||
|
bool timer_invoked = false;
|
||||||
|
|
||||||
|
int timer_id = zmq_timers_add (timers, 100, handler, &timer_invoked);
|
||||||
|
assert (timer_id);
|
||||||
|
|
||||||
|
// Timer should be invoked yet
|
||||||
|
int rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (!timer_invoked);
|
||||||
|
|
||||||
|
// Wait half the time and check again
|
||||||
|
_sleep (zmq_timers_timeout (timers) / 2);
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (!timer_invoked);
|
||||||
|
|
||||||
|
// Wait until the end
|
||||||
|
_sleep (zmq_timers_timeout (timers));
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (timer_invoked);
|
||||||
|
timer_invoked = false;
|
||||||
|
|
||||||
|
// Wait half the time and check again
|
||||||
|
long timeout = zmq_timers_timeout (timers);
|
||||||
|
_sleep (timeout / 2);
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (!timer_invoked);
|
||||||
|
|
||||||
|
// Reset timer and wait half of the time left
|
||||||
|
rc = zmq_timers_reset (timers, timer_id);
|
||||||
|
_sleep (timeout / 2);
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (!timer_invoked);
|
||||||
|
|
||||||
|
// Wait until the end
|
||||||
|
_sleep (zmq_timers_timeout (timers));
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (timer_invoked);
|
||||||
|
timer_invoked = false;
|
||||||
|
|
||||||
|
// reschedule
|
||||||
|
zmq_timers_set_interval (timers, timer_id, 50);
|
||||||
|
_sleep (51);
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (timer_invoked);
|
||||||
|
timer_invoked = false;
|
||||||
|
|
||||||
|
// cancel timer
|
||||||
|
timeout = zmq_timers_timeout (timers);
|
||||||
|
zmq_timers_cancel (timers, timer_id);
|
||||||
|
_sleep (timeout * 2);
|
||||||
|
rc = zmq_timers_execute (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (!timer_invoked);
|
||||||
|
|
||||||
|
rc = zmq_timers_close (timers);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user