mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Krzysztof Halasa <khc@pm.waw.pl>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: Re: select for UNIX sockets?
Date: 05 Jun 2003 01:27:20 +0200	[thread overview]
Message-ID: <m3n0gxfmp3.fsf@defiant.pm.waw.pl> (raw)
In-Reply-To: <1054651886.9233.35.camel@dhcp22.swansea.linux.org.uk>

[-- Attachment #1: Type: text/plain, Size: 1674 bytes --]

Alan Cox <alan@lxorguk.ukuu.org.uk> writes:

> Sort of. The wakeup may occur for several reasons and you need to check
> the return (for signals). Also the wakeup can occur when there is room
> but another thread fills it, or return room but not enough for a large
> datagram. Those don't seem to be the case on your example

I've traced the problem to datagram_poll(). This function doesn't
check if the receiver queue has at least one slot empty, it only
checks sock_writeable() i.e. if:
        atomic_read(&sk->wmem_alloc) < (sk->sndbuf / 2);

unix_dgram_sendmsg() can then block on:

        if (unix_peer(other) != sk &&
            skb_queue_len(&other->receive_queue) > other->max_ack_backlog) {
                if (!timeo) {
                        err = -EAGAIN;
                        goto out_unlock;

Now the question is how should the problem be fixed?
I've tried using modified datagram_poll():

+       unix_socket *other = NULL;

-       if (sock_writeable(sk))
+       other = unix_peer_get(sk);
+       if (sock_writeable(sk) && other &&
+           skb_queue_len(&other->receive_queue) <= other->max_ack_backlog)
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
                set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);

but unix_peer_get(sk) returns NULL.
How can I examine the receiver queue length?
Should I worry about "restarts" as in unix_dgram_sendmsg()?
Maybe someone has a fix ready?

I've attached the userspace tests, a modified version of someone's real
program - recv should be run first, send should be straced.

The problem is present in both 2.5.70 and 2.4.20rc7.
-- 
Krzysztof Halasa
Network Administrator

[-- Attachment #2: recv.c --]
[-- Type: application/octet-stream, Size: 1118 bytes --]

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>

int                 socketUn;
struct sockaddr_un  addrUn;
int                 lenUn;
int                 size = 1;
char                datagram[2000];

void sockInit();

int main() {
  sockInit();

  while(1) {
    sleep(30);

    while(size != -1){
      size = recvfrom(socketUn, &datagram, sizeof(datagram), 0,
                      (struct sockaddr*)NULL, (socklen_t *)NULL);
    /*  if (size == -1) perror("recvfrom failed: ");
        else printf("DATAGRAM: size: %d\n", size);*/
    }
    size = 0;
  }
}


void sockInit() {
  if ( unlink("/tmp/tempUn") == -1) perror("unlink failed\n");

  socketUn = socket(AF_UNIX, SOCK_DGRAM, 0);
  if (socketUn == -1) perror("socket failed");

  addrUn.sun_family = AF_UNIX;

  strcpy(addrUn.sun_path, "/tmp/tempUn");

  lenUn = strlen(addrUn.sun_path) + sizeof(addrUn.sun_family);

  if ( bind(socketUn, (struct sockaddr *)&addrUn, lenUn) == -1)
    perror("bind failed");

  fcntl(socketUn, F_SETFL, O_APPEND|O_NONBLOCK);
}


[-- Attachment #3: send.c --]
[-- Type: application/octet-stream, Size: 1159 bytes --]

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>

int                 socketUn;
struct sockaddr_un  addrUn;
int                 lenUn;
int                 size;
char                datagram[1];
int                 dgramCounter = 0;
int                 maxFdToWatch;
fd_set              writeFdToWatch;


void sockInit();


int main() {

  sockInit();

  maxFdToWatch = socketUn + 1;

  while(1) {
    FD_ZERO(&writeFdToWatch);
    FD_SET(socketUn, &writeFdToWatch);

    select(FD_SETSIZE, NULL, &writeFdToWatch, NULL, NULL);
    sleep(1);

    if (FD_ISSET(socketUn, &writeFdToWatch)) {
      size = sendto(socketUn, &datagram, sizeof(datagram), 0, (struct
sockaddr *)&addrUn, lenUn);
      if (size == -1) perror("sendto failed");
      sleep(1);
    }

    dgramCounter++;

    FD_ZERO(&writeFdToWatch);
  }
}

void sockInit() {
  socketUn = socket(AF_UNIX, SOCK_DGRAM, 0);
  if (socketUn == -1) perror("socket failed");
  addrUn.sun_family = AF_UNIX;
  strcpy(addrUn.sun_path, "/tmp/tempUn");
  lenUn = strlen(addrUn.sun_path) + sizeof(addrUn.sun_family);
}


  reply	other threads:[~2003-06-04 23:20 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-03  0:08 Krzysztof Halasa
2003-06-03 14:51 ` Alan Cox
2003-06-04 23:27   ` Krzysztof Halasa [this message]
2003-06-05 13:17     ` Krzysztof Halasa
2003-06-04 11:55 ` Jesse Pollard
2003-06-04 12:42   ` Krzysztof Halasa
2003-06-04 12:19 Petr Vandrovec
2003-06-06  0:28 ` Valdis.Kletnieks
2003-06-06  0:38   ` Petr Vandrovec
2003-06-06 12:20 MarKol
2003-06-07  0:14 ` David Schwartz
2003-06-08  0:04   ` Krzysztof Halasa
2003-06-09  3:11     ` David Schwartz
2003-06-09 17:18       ` Krzysztof Halasa
2003-06-09 17:55         ` David Schwartz
2003-06-09 22:24           ` Krzysztof Halasa
2003-06-10 13:34             ` Timothy Miller
2003-06-10 13:52               ` Richard B. Johnson
2003-06-10 14:21               ` Krzysztof Halasa
2003-06-10 19:04                 ` Jesse Pollard
2003-06-11 21:55                   ` Krzysztof Halasa
2003-06-11 22:50                     ` David Schwartz
2003-06-11 12:51                 ` Edgar Toernig
2003-06-10 21:40             ` David Schwartz
2003-06-11 22:04               ` Krzysztof Halasa
2003-06-09 23:45         ` James Stevenson
2003-06-08  4:15   ` Chris Friesen
2003-06-09  3:05     ` David Schwartz
2003-06-09 16:46   ` MarKol
2003-06-09 17:05     ` David Schwartz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3n0gxfmp3.fsf@defiant.pm.waw.pl \
    --to=khc@pm.waw.pl \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®