win32 and glib, socket data inaccessible

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

win32 and glib, socket data inaccessible

Marc Lehmann
[this is a repost, my original mail was held for moderation, but it seems the
list isn't actively being moderated at the moment]

Hi!

I am trying to port a gtk2-perl program to windows (in theory an easy
task).

However, it's using sockets, and the only way to use them in a nonblocking
way (under Gtk2) seems to be to use glib watchers. Now, the problem is
that, when my callback gets called, glib has already read the data from
the filehandle, and there doesn't seem to be support for giochannels in
the Glib module, so there is no way to actually get the data.

Is this a known problem or did I just miss the giochannel
interface? (Sorry if it's the latter case).

I am using activestate perl + tml's native win32 libs.

Thanks for any insights...

--
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      [hidden email]
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

muppet-6

Marc Lehmann said:
>
> I am trying to port a gtk2-perl program to windows (in theory an easy
> task).
>
> However, it's using sockets, and the only way to use them in a nonblocking
> way (under Gtk2) seems to be to use glib watchers. Now, the problem is
> that, when my callback gets called, glib has already read the data from
> the filehandle, and there doesn't seem to be support for giochannels in
> the Glib module, so there is no way to actually get the data.

Have you tried recv() instead of <> or sysread?  giochannel.h says "Contrary
to IO channels for file descriptors (on *Win32), you can use normal recv() or
recvfrom() on sockets even if GLib is polling them," and
g_io_channel_unix_new() on win32 calls g_io_channel_win32_new_socket() when it
determines that the fd is actually a socket.



> Is this a known problem or did I just miss the giochannel
> interface? (Sorry if it's the latter case).

Not a problem known to me, at least.

The only hint of the GIOChannel API visible at the perl level is
Glib::IO::add_watch().  This was by design, because GIOChannel provides
functionality normally provided by native perl file handles, and we made a
conscious effort not to duplicate these things.  Personally, i had no idea
that sockets behaved that way on win32.

So, er, it's probably broken.


--
muppet <scott at asofyet dot org>

_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

Torsten Schoenfeld
In reply to this post by Marc Lehmann
On Thu, 2005-06-30 at 04:00 +0200, Marc Lehmann wrote:

> [this is a repost, my original mail was held for moderation, but it seems the
> list isn't actively being moderated at the moment]

It is.  I just don't check the queued mails every day.  When I wanted to
do it the last time, the gnome.org servers were being transported to
another location.

In general, people should just subscribe to the list if they want to
post to it.

--
Bye,
-Torsten

_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

Marc Lehmann
In reply to this post by muppet-6
On Thu, Jun 30, 2005 at 10:17:15AM -0400, muppet <[hidden email]> wrote:

> > I am trying to port a gtk2-perl program to windows (in theory an easy
> > task).
> >
> > However, it's using sockets, and the only way to use them in a nonblocking
> > way (under Gtk2) seems to be to use glib watchers. Now, the problem is
> > that, when my callback gets called, glib has already read the data from
> > the filehandle, and there doesn't seem to be support for giochannels in
> > the Glib module, so there is no way to actually get the data.
>
> Have you tried recv() instead of <> or sysread?

No, because, as I wrote, glib already read the socket data, so I assumed
that recv would block just as sysread does (sysread is not really
different to recv).

However, I did try recv, and the result is as expected: it simply blocks
waiting for new data, while the data that triggered the watcher is "lost"
in the glib-internal buffer.

However, it was in some sense "false alarm", as I did some tracing with
G_IO_WIN32_DEBUG=1, and it showed this:

   fileno is 3 at igsueme line 340.
   g_io_channel_win32_new_fd: 3
   g_io_win32_create_watch: fd:3 condition:0x1 handle:0x200

If I read this correctly, it means that g_io_channel_unix_new, which tests
for both socket and normal file, detects that filehandle 3 is not a socket
but a file (it would output a warning if is a socket _and_ a file).

So this probably means that the Glib module passes in the weong filehandle
(the perl fileno, not the windows filehandle).

In 2002 or so I read about this issue, and I think you need a function to
convert between perls idea of fileno and the os idea of a fileno, and glib
should use that function.

I'll do some research.

(Damn, I tried very hard to avoid having to build perl modules for
activestate... it's sooo horrible and maybe I won't even succeed...).

> > interface? (Sorry if it's the latter case).
>
> Not a problem known to me, at least.

Well... :)

> The only hint of the GIOChannel API visible at the perl level is
> Glib::IO::add_watch().  This was by design, because GIOChannel provides
> functionality normally provided by native perl file handles, and we made a
> conscious effort not to duplicate these things.  Personally, i had no idea
> that sockets behaved that way on win32.

win32 has rather weird ways of event multiplexing. basically you have no
multiplexing but instead start a thread for every source (or at least
every type of event source). (in theory there are gazillion cool features
there (overlapped i/o, completion ports, ...), but the most basic use
cases are not solvable without threads and some weird programming).

--
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      [hidden email]
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

Marc Lehmann
On Fri, Jul 01, 2005 at 07:13:29AM +0200, Marc Lehmann <[hidden email]> wrote:
> I'll do some research.

Couldn't sleep, so I did some research now instead of later. Indeed:

glib expects an os handle.

   #ifdef USE_SOCKETS_AS_HANDLES
   #       define TO_SOCKET(x)     _get_osfhandle(x)
   #else
   #       define TO_SOCKET(x)     (x)
   #endif  /* USE_SOCKETS_AS_HANDLES */

so whenever add_watch gets a socket, it must pass in
TO_SOCKET(perlfileno), while for normal files, it has to pass in just the
perlfileno.

Now, as it has to find out wether sth. is a socket or a file, it can also
call the appropriate function inside glib, so that fixes another bug
(socket filenos and file filenos can overlap in theory).

Digging some more, it seems one can distinguish between the two by:

        io = GvIO(gv);
        if (io && IoTYPE(io) == IoTYPE_SOCKET) {

Incidentally, this would require add_watch to be changed to accept a perl
filehandle, unless somebody can deduce the type of a perl fd.

Or maybe one can always call TO_SOCKET on _all_ perl filenos, and the
result of TO_SOCKET is always the correct handle to call with into glib. I
am not sure.

(Maybe both ways would work, from the code it seems that perl vis-a-vis
the runtime lib converts sockets into "unix fds". But as glib calls fstat
on the fd, I am not sure wether TO_SOCKET would return the right thing. It
ist most clean to actually call the correct glib function instead of
having it guess).

(And I might not try it out for some time).

(And I guess I was the only person trying to use Gtk2+sockets some years
ago where it didn't work, and I guess I am still he only one trying. I
think that's a good sign, actually).

> (Damn, I tried very hard to avoid having to build perl modules for
> activestate... it's sooo horrible and maybe I won't even succeed...).
>
> > > interface? (Sorry if it's the latter case).
> >
> > Not a problem known to me, at least.
>
> Well... :)
>
> > The only hint of the GIOChannel API visible at the perl level is
> > Glib::IO::add_watch().  This was by design, because GIOChannel provides

Incidentally, native win32 perl changes the sysread into a recv anyways.
*sigh*

Good Night,

--
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      [hidden email]
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

Marc Lehmann
On Fri, Jul 01, 2005 at 07:34:56AM +0200, Marc Lehmann <[hidden email]> wrote:
> Digging some more, it seems one can distinguish between the two by:
>
>         io = GvIO(gv);
>         if (io && IoTYPE(io) == IoTYPE_SOCKET) {

Actually, why distinguish them? It's not valid to call add_watch with a
file handle, only with sockets, under most os'es, and...

ah, no, also with pipes (oops, I wonder whta glib will do with pipes -
likely it doesn't work because it tries to buffer them).

But as it is broken anyway I guess it's quite unnecessary to support anythig
besides sockets there, except maybe for an error message if you pass in the
wrong kind of handle.

--
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      [hidden email]
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

Marc Lehmann
In reply to this post by Marc Lehmann
On Fri, Jul 01, 2005 at 07:13:29AM +0200, Marc Lehmann <[hidden email]> wrote:
> I'll do some research.

It's worse. I got Glib to build.

   #ifdef USE_SOCKETS_AS_HANDLES
   #       define TO_SOCKET(x)     _get_osfhandle(x)

USE_SOCKETS_AS_HANDLES is defined, but _get_osfhandle simply returns -1
for the socket fd I pass in. Now, both fstat and the getsockname test
return true (but I don't see the warning in the code being output on the
console, so maybe glib is linked against a different getsockname? I use the
glib from http://www.gimp.org/win32).

When I pass in the fd directly to g_io_channel_win32_new_socket, the
callback is never being called (despite data being ready).

So (activestate-)perl seems to have an entirely different idea of "file
descriptor" then both MSVCRT and glib.

(I wouldn't care for activestate perl, but I can't see the alternatives,
as I am unable to build gtk+ with win32 backend in cygwin and the
only perl thats compatible with the native win32 build seems to be
activestates).

--
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      [hidden email]
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list
Reply | Threaded
Open this post in threaded view
|

Re: win32 and glib, socket data inaccessible

Marc Lehmann
In reply to this post by Marc Lehmann
On Fri, Jul 01, 2005 at 07:13:29AM +0200, Marc Lehmann <[hidden email]> wrote:
> I'll do some research.

Ok, activestateperl changed sth. "recently", does it's own filehandle
namespace, and exports win32_get_osfhandle, which finally returns the
correct handle (and is aliases to _get_osfhandle in older releases).

I checked in a patch to Glib. Feel free to inflict pain on me if I did
something bad :)

In any case, as the fd space seems not to be the msvcrt fd namespace and I
have no idea how to convert a perl fd to a msvcrt fd (which glib seems to
need), I just call g_io_channel_win32_new_socket on win32 (it doesn't make
much sense to add watchers to other types of fd, I guess, as pipes seem to
be sockets, too, under windows).

This shouldn't break anything (after all, it didn't work before), not
even cygwin, which hopefully doesn't define USE_SOCKETS_AS_HANDLES, but who
knows...

(If somebody tells me how to create a ppm I can create one, too).

--
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      [hidden email]
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE
_______________________________________________
gtk-perl-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list