Glib socket monitoring on Windows puts them in non-blocking mode

The following code does not work correctly on Windows (but works on Linux):

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setblocking(True)
    sock.connect(address)
    gobject.io_add_watch(
            sock.fileno(),
            gobject.IO_OUT | gobject.IO_ERR | gobject.IO_HUP,
            callback)

Fragments of comments in different places of the glib source, and in other places it is mentioned that on Windows sockets are placed in non-blocking mode during polling. As a result, the callback is self.outgoing_cbconstantly called, and writing to the socket fails:

[Errno 10035] A non-blocking socket operation could not be completed immediately

A call sock.setblocking(True)before writing doesn't seem to work around. Reducing the priority of the poll and ignoring the error message, it works as expected, but it does not throw many events and consumes a lot of CPU. Is there a way around this limitation in Windows?

Update

, POLLOUT , EAGAIN/EWOULDBLOCK. , , , Windows . , gobject.IO_OUT, , , , .

Linux, , , IO_OUT, . / Windows.

man poll:

   poll()  performs a similar task to select(2): it waits for one of a set
   of file descriptors to become ready to perform I/O.
          POLLOUT
                 Writing now will not block.

man select:

A file descriptor  is considered ready if it is possible to perform the corre‐
sponding I/O operation (e.g., read(2)) without blocking.
+3
4

-? , -.

, :

  • , .

  • IO_OUT ( poll() , POLLOUT) , .

  • poll() ( ) , , . EAGAIN/EWOULDBLOCK, , , , . , POLLOUT, .

( , Win32 WSAEventSelect WaitForMultipleObjects() poll(), ...)

, . "" , , . , ... , , , , -.

+1
+1

, ( MFC , ), :

EAGAIN , select, .. , , select() rc = 0, ...

, , ( ):

set_nonblocking.
count= 0.
do {
   FDSET writefds;
   add skt to writefds.
   call select with writefds and a reaonsable timeout.
   if (select fails with timeout) {
       die with some error;
   } 

   howmany= send(skt, buf+count, total-count).
   if (howmany>0) {
       count+= howmany.
   }
} while (howmany>0 && count<total);
0

Twisted, GTK ( Windows) , Windows, , .

0

Source: https://habr.com/ru/post/1721475/


All Articles