g_io_channel_win32_poll() Problem on Windows

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

g_io_channel_win32_poll() Problem on Windows

Faik

Hi,

I am trying to port a Linux application to Windows that highly depends on GLib. I compiled GLib with MSVC 2015. The application uses g_poll() in a place.  In g_poll() GNOME documentation, it states that
If you need to use g_poll() in code that has to run on Windows, the easiest solution is to construct all of your  GPollFDswith  g_io_channel_win32_make _pollfd().

I will provide some small code segments to provide you insight:

                                               .
                                               .
//  In arv_gv_discover_socket_list_new() function            
#ifdef _WIN32
        GIOChannel * channel = g_io_channel_win32_new_socket (discover_socket->socket);
        g_io_channel_win32_make_pollfd(channel,G_IO_IN,&socket_list->poll_fds[i]);
#else
        socket_list->poll_fds[i].fd = g_socket_get_fd (discover_socket->socket);
        socket_list->poll_fds[i].events =  G_IO_IN;
        socket_list->poll_fds[i].revents = 0;
#endif                                          .
                                               .



// In _discover() function
                                               .
                                               .
                                                                                
    arv_gv_discover_socket_list_send_discover_packet (socket_list);  

            
    do {
#ifdef _WIN32
// g_io_channel_win32_make _pollfd() documentation says call this
        if (g_io_channel_win32_poll(socket_list->poll_fds, socket_list->n_sockets, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0)  
#else
        if (g_poll(socket_list->poll_fds, socket_list->n_sockets, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0)       
#endif        
        {
            arv_gv_discover_socket_list_free (socket_list);
            return NULL;
        }

                                               .
                                               .

As you might guess, in  arv_gv_discover_socket_list_new() function,  GPollFDs are created and in _discover() function, a broadcast message is sent and then  polled for reply. but no luck, still in _discover(), it time outs.  By the way, in Linux, the same application works smootly.
I also checked the discovery packet was actually emitted, and I saw a camera discovery ack packet coming to my network adapter via WireShark.
Since I am newbie to GLib, I cannot be sure if this modification is incorrect or GLib implementation is incorrect. Can you help me to resolve the problem?
Thanks.
PS: The Linux project is Aravis 0.5.9.  (http://ftp.gnome.org/pub/GNOME/sources/aravis/0.5/)

_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
LRN
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: g_io_channel_win32_poll() Problem on Windows

LRN
On 7/27/2017 2:06 PM, Faik wrote:

> arv_gv_discover_socket_list_send_discover_packet(socket_list);
>
> do{
>
> #ifdef_WIN32
>
> // g_io_channel_win32_make _pollfd() documentation says call this
>
> if(g_io_channel_win32_poll(socket_list->poll_fds,socket_list->n_sockets,ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS)==0)
>
>
> #else
>
> if(g_poll(socket_list->poll_fds,socket_list->n_sockets,ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS)==0)
>
> #endif
>
I don't see the documentation in on that function in glib git master.
Also, in glib git master g_io_channel_win32_make_pollfd() just calls g_poll()
after checking that number of FDs is non-zero, although calling g_poll() with
zero FDs is not an error.

> As you might guess, in  arv_gv_discover_socket_list_new() function,  GPollFDs
> are created and in _discover() function, a broadcast message is sent and then
>  polled for reply. but no luck, still in _discover(), it time outs.  By the
> way, in Linux, the same application works smootly.
> I also checked the discovery packet was actually emitted, and I saw a camera
> discovery ack packet coming to my network adapter via WireShark.
Portable I/O is tricky. If i were in your place, i would write the simplest
possible code that does this thing (creates a socket, sends a broadcast
message, then waits for a reply) using W32 socket API only. Once *that* works,
figure out what glib is doing differently. Since you're providing the socket
object to glib, at least socket creation part is already in your hands. IIRC,
glib calls WSACreateEvent() to create an event handle, then binds it to the
socket using WSAEventSelect(), then just waits on the event handle using
conventional WaitForMultipleObjects...() (in your case WaitForSingleObject
would probably be enough). Once it indicates that the event is set, glib calls
WSAEnumNetworkEvents () to see which socket events happened.

Is it possible that the system (and glib) at some point signaled you that the
socket in question can, in fact, be read() from, but you (or glib) ignored
that? In that case WsaEventSelect() won't report FD_READ again, until recv() is
called.

You can also try to run with G_IO_WIN32_DEBUG=1 and see what the output is.

--
O< ascii ribbon - stop html email! - http://arc.pasp.de/

_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

0x6759BA74.asc (3K) Download Attachment
signature.asc (836 bytes) Download Attachment
LRN
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: g_io_channel_win32_poll() Problem on Windows

LRN
On 7/27/2017 2:56 PM, LRN wrote:

> On 7/27/2017 2:06 PM, Faik wrote:
>
>> As you might guess, in  arv_gv_discover_socket_list_new() function,  GPollFDs
>> are created and in _discover() function, a broadcast message is sent and then
>>  polled for reply. but no luck, still in _discover(), it time outs.  By the
>> way, in Linux, the same application works smootly.
>> I also checked the discovery packet was actually emitted, and I saw a camera
>> discovery ack packet coming to my network adapter via WireShark.
> Portable I/O is tricky. If i were in your place, i would write the simplest
> possible code that does this thing (creates a socket, sends a broadcast
> message, then waits for a reply) using W32 socket API only. Once *that* works,
> figure out what glib is doing differently. Since you're providing the socket
> object to glib, at least socket creation part is already in your hands. IIRC,
> glib calls WSACreateEvent() to create an event handle, then binds it to the
> socket using WSAEventSelect(), then just waits on the event handle using
> conventional WaitForMultipleObjects...() (in your case WaitForSingleObject
> would probably be enough). Once it indicates that the event is set, glib calls
> WSAEnumNetworkEvents () to see which socket events happened.
>
After trying this myself (for unrelated reasons), i found that *only*
giochannel GSource does WSAEventSelect() on a socket event (in
g_io_win32_prepare()) to bind it to an event handle, which can then be polled.
If you are not using a main loop (and GSource), then this doesn't happen, and
the events you feed to g_poll() are completely inert.

Thus, apart from creating sockets yourself, you should also call call
WSAEventSelect(). It might be possible to offload this to glib by pretending to
be a main loop, but driving stuff manually, but i haven't checked that yet.

--
O< ascii ribbon - stop html email! - http://arc.pasp.de/

_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

0x6759BA74.asc (3K) Download Attachment
signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: g_io_channel_win32_poll() Problem on Windows

Paul Davis


On Fri, Jul 28, 2017 at 4:37 AM, LRN <[hidden email]> wrote:


After trying this myself (for unrelated reasons), i found that *only*
giochannel GSource does WSAEventSelect() on a socket event (in
g_io_win32_prepare()) to bind it to an event handle, which can then be polled.
If you are not using a main loop (and GSource), then this doesn't happen, and
the events you feed to g_poll() are completely inert.

This is true on all platforms. The "responsiveness" of all GSources depends on a main loop that polls/selects/does-some-platform-equivalent-of-wait-for-something.
 

_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
LRN
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: g_io_channel_win32_poll() Problem on Windows

LRN
On 7/28/2017 3:08 PM, Paul Davis wrote:

>
>
> On Fri, Jul 28, 2017 at 4:37 AM, LRN wrote:
>> After trying this myself (for unrelated reasons), i found that *only*
>> giochannel GSource does WSAEventSelect() on a socket event (in
>> g_io_win32_prepare()) to bind it to an event handle, which can then be polled.
>> If you are not using a main loop (and GSource), then this doesn't happen, and
>> the events you feed to g_poll() are completely inert.
>
> This is true on all platforms. The "responsiveness" of all GSources depends on
> a main loop that
> polls/selects/does-some-platform-equivalent-of-wait-for-something.
>  
That's not what i meant. On Windows g_poll() is just a glorified
WaitForMultipleObjectsEx() that waits on an array of handles.
The polling of sockets is done in a very circuitous way - and event is bound to
a socket with WSAEventSelect(), then that event is polled, then, once the event
is signaled, the code in W32-socket-based GSource calls WSAEnumNetworkEvents()
to get the socket-level events triggered the signaling.

For blocking I/O (W32 nameless pipes) same thing applies - the events that
g_poll() waits upon are, in fact, special events attached to a separate thread
that does the actual I/O.

g_poll() itself does almost nothing. The revents that it fills in the GPollFD
structs are just copies of the events field (the copying is done when the
corresponding event is signaled).

So, the main takeaway here is that you should either do what GSource+gmainloop
do (source prepare, then g_poll, then source check), or just use GSource+gmainloop.

--
O< ascii ribbon - stop html email! - http://arc.pasp.de/

_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list

0x6759BA74.asc (3K) Download Attachment
signature.asc (836 bytes) Download Attachment
LRN
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: g_io_channel_win32_poll() Problem on Windows

LRN
In reply to this post by Faik
On 7/27/2017 1:51 PM, mualloc . wrote:

> arv_gv_discover_socket_list_send_discover_packet(socket_list);
>
>
> do{
>
> #ifdef_WIN32
>
> // g_io_channel_win32_make _pollfd() documentation says call this
>
> if(g_io_channel_win32_poll(socket_list->poll_fds,socket_list->n_sockets,ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS)==0)
>
>
> #else
>
> if(g_poll(socket_list->poll_fds,socket_list->n_sockets,ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS)==0)
>
> #endif
>

I don't see the documentation in on that function in glib git master.
Also, in glib git master g_io_channel_win32_make_pollfd() just calls g_poll()
after checking that number of FDs is non-zero, although calling g_poll() with
zero FDs is not an error.

> As you might guess, in  arv_gv_discover_socket_list_new() function,  GPollFDs
> are created and in _discover() function, a broadcast message is sent and then
>  polled for reply. but no luck, still in _discover(), it time outs.  By the
> way, in Linux, the same application works smootly.
> I also checked the discovery packet was actually emitted, and I saw a camera
> discovery ack packet coming to my network adapter via WireShark.
Portable I/O is tricky. If i were in your place, i would write the simplest
possible code that does this thing (creates a socket, sends a broadcast
message, then waits for a reply) using W32 socket API only. Once *that* works,
figure out what glib is doing differently. Since you're providing the socket
object to glib, at least socket creation part is already in your hands. IIRC,
glib calls WSACreateEvent() to create an event handle, then binds it to the
socket using WSAEventSelect(), then just waits on the event handle using
conventional WaitForMultipleObjects...() (in your case WaitForSingleObject
would probably be enough). Once it indicates that the event is set, glib calls
WSAEnumNetworkEvents () to see which socket events happened.

Is it possible that the system (and glib) at some point signaled you that the
socket in question can, in fact, be read() from, but you (or glib) ignored
that? In that case WsaEventSelect() won't report FD_READ again, until recv() is
called.

You can also try to run with G_IO_WIN32_DEBUG=1 and see what the output is.

--
O< ascii ribbon - stop html email! - http://arc.pasp.de/
_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Loading...