2012-03-20 1 views
3

J'essaie d'intégrer zeromq dans une boucle principale glib, mais je n'arrive pas à comprendre pourquoi mon programme est défectueux.Pourquoi suis-je segfault lors du remplacement de poll() par zmq_poll() dans le contexte principal de glib?

est ici la fonction qui garantit une erreur de segmentation après l'exécution aussi g_main_loop_run (boucle):

/** set poll fn to operate on zmq or unix sockets */ 
g_main_context_set_poll_func(g_context, (GPollFunc) zmq_poll); 

Je pensais que cela fonctionnerait, étant donné que zmq_poll partage la même structure que poll et appelant cette même fonction s/zmq_poll/poll/fonctionne bien.

La version dépouillée de mon code avec elle encore segfault'ing: http://paste.pocoo.org/show/568289/.

(non testé) Version complète: 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 

compilez le code (en supposant que vous avez GStreamer et ZeroMQ installé) avec:

gcc --debug `pkg-config gstreamer-0.10 --libs` -lzmq `pkg-config gstreamer-0.10 --cflags` -o test test.c 

Qu'est-ce que je fais mal?

Toute aide est appréciée, merci.

EDIT: Je l'ai à travailler avec ce alexander suggéré en utilisant cette fonction comme mon remplacement vote rapide:

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_); 
} 

Pour être honnête, je ne suis même pas sûr de savoir comment cela a fonctionné aussi bien qu'il l'a fait, mais je suis un débutant C et je ne sais pas trop comment faire une adaptation plus adaptative().

Répondre

2

format de données attendu pour le rappel GPollFunc est

struct GPollFD { 
#if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8 
    gint64 fd; 
#else 
    gint  fd; 
#endif 
    gushort events; 
    gushort revents; 
}; 

format de données attendu pour zmq_poll est

typedef struct 
{ 
    void //*socket//; 
    int //fd//; 
    short //events//; 
    short //revents//; 
} zmq_pollitem_t; 

La solution est d'écrire l'adaptateur et le transmettre à 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_); 
} 
Questions connexes