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);
}
next prev parent 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®