5

MSDN says that : Listen() is a blocking call. Code snippet from a function in which i have used listen() is shown below:

sockaddr_in addr    = {0};
int     addrlen = sizeof(addr);
SOCKET  sock_listen;

if(-1 == (sock_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
{
    cout<<"error";
}   

addr.sin_family = AF_INET;
/* Network byte ordered address for loopback */
addr.sin_addr.s_addr= inet_addr("127.0.0.1");
/* Let service provider assign a unique port from dynamic client port range */  
addr.sin_port   = 0;                        

if(-1 == bind(sock_listen, (const sockaddr *)&addr, addrlen))       
{
    CloseHandle((HANDLE)sock_listen_fd);
    cout<<"error";
}

if(-1 == getsockname(sock_listen, (sockaddr *)&addr, &addrlen))
{     
    CloseHandle((HANDLE)sock_listen);
    cout<<"error";
}

u_long mode = 0;
if(SOCKET_ERROR == ioctlsocket(sock_listen, FIONBIO, &mode))
{
    cout<<"ioctl failed";
}

if(SOCKET_ERROR == listen(sock_listen, 1))
{
    cout<<"listen error";
}
cout<<"Passed listen";
if(SOCKET_ERROR == (s = ACL_accept(sock_listen_fd, NULL, NULL)))
{
       cout<<"accept error";
}

By default a socket handle created as blocking type. Inorder to further ensure it called ioctlsocket() to make the socket handle blocking type.

The output is : Passed listen

So, the thread is not blocking at listen(), instead it blocks on accept which according to my knowledge, is the right way. Also in Linux MAN page it is clearly explained :

listen() marks the socket referred to by socket fd as a passive socket, i.e, as a socket that will be used to accept incoming connection requests using accept()

Then why does MSDN says that listen is a blocking Winsock call. Do they just mean any internal waiting for some event?

Aravind
  • 555
  • 1
  • 3
  • 12

3 Answers3

3

All the documentation says is that listen might block, not that it definitely will. It might also be blocking only very briefly, e.g., to wait for the NIC device driver to complete existing activity.

Windows Sockets allows for the installation of third-party providers to support additional protocols or existing protocols with extra features. Since the Winsock SPI does not prohibit third-party providers from blocking on listen, applications should follow the advice provided by MSDN with regards to APCs and nested Winsock calls.

It seems likely that the built-in TCP/IP provider never blocks on listen but AFAIK there is no explicit guarantee of this.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
2

It might be a blocking call in a sense that the OS might need to make sure that the calling thread has exclusive access to the socket, which requires some sort of a lock, which in turn might block the caller if some other thread holds that lock.

Edit 0:

In general, any call into the operating system is an opportunity for a userland thread to be de-scheduled in favor of other higher priority processing. This usually isn't called "blocking" though, but "sleeping" or being "preempted".

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • Holds that lock for what conflicting purpose? I'd call it an 'atomic' call rather than a 'blocking' call. – user207421 May 21 '13 at 12:18
  • Yeah, you might be right. It certainly is not "blocking" on any sane OS. But then Windows is far from "sane". Will change the wording though, thanks. – Nikolai Fetissov May 21 '13 at 12:36
1

If MSDN says that, it is mistaken. It isn't a blocking call. There's nothing to block on, certainly no 'external network event'.

The paragraph that says so is clearly boilerplate copied into too many places.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I don't know ... the Windows Sockets SPI doesn't appear to prohibit third-party protocol providers from blocking on `listen`. – Harry Johnston May 22 '13 at 04:14
  • So all we need now is even one plausible suggestion as to what exactly they might block it +on.+ I don't go for your suggestion about the NIC driver. `listen()` has nothing to do with the network, yet. – user207421 May 22 '13 at 04:58
  • I can think of one example that is only slightly contrived: if the network provider is transparently redirecting the socket to a remote system, it might need to wait for that remote system to respond. I'm not aware of any existing software that does this sort of thing, but it could be useful; it would allow multiple computers to share a single IP address, without the limitations of NAT. – Harry Johnston May 22 '13 at 08:13
  • Also, while a conventional NIC doesn't need to be told about a `listen` call, mightn't hardware offloading change this? – Harry Johnston May 22 '13 at 08:15