Why am I segfault'ing when replacing poll () with zmq_poll () in the main glib context?
I'm trying to integrate zeromq into the main glib loop, but I can't figure out why my program is segfault'ing.
Here's a function to guarantee a segfault after running g_main_loop_run (loop):
/** set poll fn to operate on zmq or unix sockets */
g_main_context_set_poll_func( g_context, (GPollFunc) zmq_poll );
I thought it would work, given that it zmq_poll
shares the same structure as poll
calling this same function with s / zmq_poll / poll / works fine.
The split version of my code is still segfault'ing with it: http://paste.pocoo.org/show/568289/ .
(untested) Full version: http://paste.pocoo.org/show/568292/ .
StackTrace:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6a2bd50 in ?? ()
from /usr/lib/libzmq.so.1
(gdb) bt
#0 0x00007ffff6a2bd50 in ?? ()
from /usr/lib/libzmq.so.1
#1 0x00007ffff6a34b4d in zmq_getsockopt ()
from /usr/lib/libzmq.so.1
#2 0x00007ffff6a34e1b in zmq_poll ()
from /usr/lib/libzmq.so.1
#3 0x00007ffff6c89dc8 in ?? ()
from /usr/lib/libglib-2.0.so.0
#4 0x00007ffff6c8a5f2 in g_main_loop_run ()
from /usr/lib/libglib-2.0.so.0
#5 0x0000000000402978 in main (argc=1,
argv=0x7fffffffe5e8) at server.c:229
Compile the code (if you have gstreamer and zeromq installed):
gcc --debug `pkg-config gstreamer-0.10 --libs` -lzmq `pkg-config gstreamer-0.10 --cflags` -o test test.c
What am I doing wrong?
Any help is appreciated, thanks.
EDIT: Worked with what Alexander suggested, using this function as a replacement for my survey:
gint zmq_poll_adapter(GPollFD *ufds, guint nfsd, gint timeout_)
{
zmq_pollitem_t ufds0[nfsd];
int i;
for (i = 0; i < nfsd; i++)
{
ufds0[i].socket = NULL;
ufds0[i].fd = ufds[i].fd;
ufds0[i].events = ufds[i].events;
ufds0[i].revents = ufds[i].revents;
}
zmq_poll(ufds0, nfsd, timeout_);
}
To be honest, I'm not even sure how it worked as well as it did, but I'm new to C and don't know how to do more responsive adaptation ().
source to share
Expected data format for GPollFunc callback
struct GPollFD {
#if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8
gint64 fd;
#else
gint fd;
#endif
gushort events;
gushort revents;
};
The expected data format for zmq_poll is
typedef struct
{
void //*socket//;
int //fd//;
short //events//;
short //revents//;
} zmq_pollitem_t;
The solution is to write an adapter and pass it to g_main_context_set_poll_func:
gint zmq_poll_adapter(GPollFD *ufds, guint nfsd, gint timeout_)
{
zmq_pollitem_t *ufds0 = adapt(ufds, nfsd);
zmq_poll(ufds0, nfsd, timeout_);
}
source to share