Commit c995de65 authored by KennyTM~'s avatar KennyTM~

Allow the ZMQ_MONITOR code compilable on gcc 4.7 on Linux.

The current ZMQ_MONITOR code does not compile in gcc 4.7, as -pedantic
and -Werror are enabled, and ISO C++ doesn't allow casting between
normal pointers (void*) and function pointers, as pedantically their
size could be different. This caused the library not compilable. This
commit workaround the problem by introducing one more indirection, i.e.
instead of calling

    (void *)listener

which is an error, we have to use

    *(void **)&listener

which is an undefined behavior :) but works on most platforms

Also, `optval_ = monitor` will not set the parameter in getsockopt(),
and the extra casting caused the LHS to be an rvalue which again makes
the code not compilable. The proper way is to pass a pointer of function
pointer and assign with indirection, i.e. `*optval_ = monitor`.

Also, fixed an asciidoc error in zmq_getsockopt.txt because the `~~~~`
is too long.
parent 89d5054e
......@@ -456,7 +456,7 @@ Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.
ZMQ_MONITOR: Registers a callback for socket state changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Registers a callback function / event sink for changes in underlying socket state.
The default value of `NULL` means no monitor callback function.
......
......@@ -325,7 +325,7 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
errno = EINVAL;
return -1;
}
monitor = ((zmq_monitor_fn*) optval_);
monitor = *((zmq_monitor_fn**) &optval_);
return 0;
}
}
......@@ -550,8 +550,8 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
errno = EINVAL;
return -1;
}
((zmq_monitor_fn*) optval_) = monitor;
*optvallen_ = sizeof (void *);
*((zmq_monitor_fn**) &optval_) = monitor;
*optvallen_ = sizeof (zmq_monitor_fn*);
return 0;
}
......
......@@ -20,6 +20,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include "session_base.hpp"
#include "socket_base.hpp"
#include "i_engine.hpp"
......
......@@ -99,16 +99,18 @@ int main (int argc, char *argv [])
assert (rep);
// Expects failure - invalid size
rc = zmq_setsockopt (rep, ZMQ_MONITOR, (void *)listening_sock_monitor, 20);
zmq_monitor_fn *monitor;
monitor = listening_sock_monitor;
rc = zmq_setsockopt (rep, ZMQ_MONITOR, *(void **)&monitor, 20);
assert (rc == -1);
assert (errno == EINVAL);
rc = zmq_setsockopt (rep, ZMQ_MONITOR, (void *)listening_sock_monitor, sizeof (void *));
rc = zmq_setsockopt (rep, ZMQ_MONITOR, *(void **)&monitor, sizeof (void *));
assert (rc == 0);
void *monitor;
size_t sz = sizeof (void *);
rc = zmq_getsockopt (rep, ZMQ_MONITOR, monitor, &sz);
rc = zmq_getsockopt (rep, ZMQ_MONITOR, &monitor, &sz);
assert (rc == 0);
assert (monitor == listening_sock_monitor);
......@@ -116,7 +118,7 @@ int main (int argc, char *argv [])
rc = zmq_setsockopt (rep, ZMQ_MONITOR, NULL, 0);
assert (rc == 0);
rc = zmq_getsockopt (rep, ZMQ_MONITOR, monitor, &sz);
rc = zmq_getsockopt (rep, ZMQ_MONITOR, &monitor, &sz);
assert (rc == 0);
assert (monitor == listening_sock_monitor);
......@@ -126,7 +128,8 @@ int main (int argc, char *argv [])
void *req = zmq_socket (ctx, ZMQ_REQ);
assert (req);
rc = zmq_setsockopt (req, ZMQ_MONITOR, (void *)connecting_sock_monitor, sizeof (void *));
monitor = connecting_sock_monitor;
rc = zmq_setsockopt (req, ZMQ_MONITOR, *(void **)&monitor, sizeof (void *));
assert (rc == 0);
rc = zmq_connect (req, "tcp://127.0.0.1:5560");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment