/ Forside / Teknologi / Operativsystemer / Linux / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Linux
#NavnPoint
o.v.n. 11177
peque 7911
dk 4814
e.c 2359
Uranus 1334
emesen 1334
stone47 1307
linuxrules 1214
Octon 1100
10  BjarneD 875
Linux sockets i close_wait - final cut.
Fra : Stig Johansen


Dato : 31-05-08 06:44

Hej alle.

I fortsættelse af mine tidligere tråde, hvor jeg har bøvlet med mere eller
mindre tilfældige hændelser, der medførte, dels et infinite loop, dels en
socket, der blev efterladt i close_wait, ser det ud til problemet er løst.

Det var Søren(Soren/Soeren?) der ledte mig på sporet af en bug i
Linux/select().

Jeg havde ca. denne konstruktion:
--------
while select(....) = 1 // --> read ready
bufflen := recv(socket)
--------

I og med selecten angiver at der er data ready, havde jeg ikke testet på den
efterfølgende recv.

Det har jeg ændret, og laver en break hvis recv <= 0.
For mig er det lidt slamkode med sådan en implicit goto, men 'WTH'...

Der er tilsyneladende omstændigheder, hvor en select melder receive ready i
det uendelige, uagtet af recv melder 0 eller fejl.

Jeg bliver nødt til at skrive muligvis løst, for det har ikke opstået
(endnu) siden i søndags, altså på 6 dage.

Det her skal blot betragtes som en tilbagemelding af hensyn til fremtidige
Googlere, der evt. står med samme problem.

--
Med venlig hilsen
Stig Johansen

 
 
Kent Friis (31-05-2008)
Kommentar
Fra : Kent Friis


Dato : 31-05-08 08:05

Den Sat, 31 May 2008 07:44:01 +0200 skrev Stig Johansen:
> Hej alle.
>
> I fortsættelse af mine tidligere tråde, hvor jeg har bøvlet med mere eller
> mindre tilfældige hændelser, der medførte, dels et infinite loop, dels en
> socket, der blev efterladt i close_wait, ser det ud til problemet er løst.
>
> Det var Søren(Soren/Soeren?) der ledte mig på sporet af en bug i
> Linux/select().

Hvor ser du bug'en?

> Jeg havde ca. denne konstruktion:
> --------
> while select(....) = 1 // --> read ready
> bufflen := recv(socket)
> --------
>
> I og med selecten angiver at der er data ready, havde jeg ikke testet på den
> efterfølgende recv.
>
> Det har jeg ændret, og laver en break hvis recv <= 0.
> For mig er det lidt slamkode med sådan en implicit goto, men 'WTH'...
>
> Der er tilsyneladende omstændigheder, hvor en select melder receive ready i
> det uendelige, uagtet af recv melder 0 eller fejl.

Ja, ved EOF (Connection closed) eller fejl (fx Connection reset by
peer).

Det skal den gøre, alternativt ville man jo stå og vente i select()
i det uendelige, og aldrig nå ned til den recv() der skal modtage
data'ene.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Soren (News) (31-05-2008)
Kommentar
Fra : Soren (News)


Dato : 31-05-08 09:06

Kent Friis <nospam@nospam.invalid> writes:

[snip]
>> Det var Søren(Soren/Soeren?) der ledte mig på sporet af en bug i
>> Linux/select().
>
> Hvor ser du bug'en?

Eh, siden jeg nu bliver inddraget, saa var den bug, jeg kommenterede paa,
en bug i Sun's JVM's brug af select(..) under Linux.

[snip]
>> Jeg havde ca. denne konstruktion:
>> --------
>> while select(....) = 1 // --> read ready
>> bufflen := recv(socket)
>> --------

select() returnerer ikke altid 1, men antallet af fd'ere, som har et
event (read, write, exception) ventende, og, -1 hvis der ikke er nogen
ventende events. Den Sun bug du refererede til, lignede noget med at de
ikke brugte timeout med select(). Hvis du ikke bruger timeout (og tjekker
for -1), så vil du også kunne få "hængende" fd'ere i en periode uden
I/O på de select()'ede fd'ere (men det ligner ikke umiddeltbart dit
problem hvis du har masser af I/O).

[snip]
>> I og med selecten angiver at der er data ready, havde jeg ikke testet på den
>> efterfølgende recv.

Igen, select()'en siger ikke "data ready" men at der er et ventende event.
"man recv" siger tydeligt hvad man kan forvente fra recv()

---
RETURN VALUE
These calls return the number of bytes received, or -1 if an error
occurred. The return value will be 0 when the peer has performed an
orderly shutdown.
---

(Beklager det lige kom som follow-up paa Kent's post)


Mvh,
Soren

Stig Johansen (31-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 31-05-08 15:54

Soren (News wrote:

> select() returnerer ikke altid 1, men antallet af fd'ere, som har et
> event (read, write, exception) ventende, og, -1 hvis der ikke er nogen
> ventende events.

I det her tilfælde havde jeg kun 1 fd - med timeout.

> Igen, select()'en siger ikke "data ready" men at der er et ventende event.
> "man recv" siger tydeligt hvad man kan forvente fra recv()

Det er jeg med på, men hvis jeg kun har en fd, og kun venter på readevent,
igen med timeout, så ville jeg forvente at der er noget til den
efterfølgende recv.

> (Beklager det lige kom som follow-up paa Kent's post)

Jeg har fået løst mit (Linux) problem, og det at jeg nævnte dig, var faktisk
ment som en særlig tak til dig, og den anden Soeren?, som er de(n) eneste
der har bidraget med noget konstruktivt.

--
Med venlig hilsen
Stig Johansen

Soren (News) (31-05-2008)
Kommentar
Fra : Soren (News)


Dato : 31-05-08 21:07

Stig Johansen <wopr.dk@gmaill.com> writes:

[snip]
> I det her tilfælde havde jeg kun 1 fd - med timeout.

Ja, gaettede ogsaa paa at det mest var pseudo-kode du fremviste
Ville bare uddybe hvis du stadig havde problemer med det.

> Jeg har fået løst mit (Linux) problem, og det at jeg nævnte dig, var faktisk

(Af nysgerrighed, har du testet paa andre "POSIX-agtige" systemer?)


Mvh,
Soren

Ukendt (31-05-2008)
Kommentar
Fra : Ukendt


Dato : 31-05-08 22:21

Soren (News) skrev den 31-05-2008 22:06:

>> Jeg har fået løst mit (Linux) problem, og det at jeg nævnte dig, var faktisk
>
> (Af nysgerrighed, har du testet paa andre "POSIX-agtige" systemer?)

Tillad mig at foreslå OpenSolaris. Netværkskoden der kan man med en vis
rimelighed forvente ER i orden.

--
Thorbjørn Ravn Andersen "... plus... Tubular Bells!"

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 07:12

Thorbjørn Ravn Andersen wrote:

> Soren (News) skrev den 31-05-2008 22:06:
>
>>> Jeg har fået løst mit (Linux) problem, og det at jeg nævnte dig, var
>>> faktisk
>>
>> (Af nysgerrighed, har du testet paa andre "POSIX-agtige" systemer?)

Jeg har ikke rigtig muligheden for at teste på andet.
Der er tale om, ganske meget, (windows) kode i Borlands Delphi/Pascal, som
er opsamlet gennem de sidste 20 år, dog kun siden '95 på server/sockets
m.v.

> Tillad mig at foreslå OpenSolaris. Netværkskoden der kan man med en vis
> rimelighed forvente ER i orden.

Det ville jeg også gerne, men Borland/'vi', har brændt nallerne på Linux, så
spørgsmålet er om 'vi' nogensinde gider røre ved det(Linux) igen.

Hvis Linux skulle blive aktuel, er der muligvis FreePascal, men min Kylix
indeholder et massivt underbibliotek/komponetbibliotek (incl source til
betalende kunder) til alt muligt incl. XML/Webservices osv.. osv..

Min interesse er ikke større end på 'recompile and try' - stadiet, da det
virker fint på Windows.

Der går også rygter om, at MS arbejder på at lave en stripped down
serverversion, så det kan være at Linux slet ikke er interessant alligevel.

--
Med venlig hilsen
Stig Johansen

Stig Johansen (31-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 31-05-08 15:45

Kent Friis wrote:

> Hvor ser du bug'en?

<http://linux.die.net/man/2/select>

Overskrift Bugs:
-----------------
........
Under Linux, select() may report a socket file descriptor as "ready for
reading", while nevertheless a subsequent read blocks. This could for
example happen when data has arrived but upon examination has wrong
checksum and is discarded. There may be other circumstances in which a file
descriptor is spuriously reported as ready.
........

--
Med venlig hilsen
Stig Johansen

Anders Wegge Jakobse~ (31-05-2008)
Kommentar
Fra : Anders Wegge Jakobse~


Dato : 31-05-08 16:02

Stig Johansen <wopr.dk@gmaill.com> writes:

> Kent Friis wrote:
>
>> Hvor ser du bug'en?
>
> <http://linux.die.net/man/2/select>
>
> Overskrift Bugs:
> -----------------
> .......
> Under Linux, select() may report a socket file descriptor as "ready for
> reading", while nevertheless a subsequent read blocks. This could for
> example happen when data has arrived but upon examination has wrong
> checksum and is discarded. There may be other circumstances in which a file
> descriptor is spuriously reported as ready.
> .......

Det lyder nu mere som den modsatte udgave af det problem du sad med.

--
// Wegge
<http://blog.wegge.dk> - Her hænger jeg også ud.
<http://geowiki.wegge.dk/wiki/Forside> - Alt om geocaching.
Bruger du den gratis spamfighther ser jeg kun dine indlæg *EN* gang.

Kent Friis (31-05-2008)
Kommentar
Fra : Kent Friis


Dato : 31-05-08 17:02

Den Sat, 31 May 2008 17:02:16 +0200 skrev Anders Wegge Jakobsen:
> Stig Johansen <wopr.dk@gmaill.com> writes:
>
>> Kent Friis wrote:
>>
>>> Hvor ser du bug'en?
>>
>> <http://linux.die.net/man/2/select>
>>
>> Overskrift Bugs:
>> -----------------
>> .......
>> Under Linux, select() may report a socket file descriptor as "ready for
>> reading", while nevertheless a subsequent read blocks. This could for
>> example happen when data has arrived but upon examination has wrong
>> checksum and is discarded. There may be other circumstances in which a file
>> descriptor is spuriously reported as ready.
>> .......
>
> Det lyder nu mere som den modsatte udgave af det problem du sad med.

Enig. Og iøvrigt står ovenstående ikke i "man 2 select" på mit system,
så det kan være en gammel bug fra Linux-1.2 tiden... Havde det været
et problem man render ind i, ville Linux være ubrugeligt til webservere
og lignende.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 06:55

Kent Friis wrote:

> Den Sat, 31 May 2008 17:02:16 +0200 skrev Anders Wegge Jakobsen:
>> Stig Johansen <wopr.dk@gmaill.com> writes:
>>
>>> Kent Friis wrote:
>>>
>>>> Hvor ser du bug'en?
>>>
>>> <http://linux.die.net/man/2/select>
>>>
>>> Overskrift Bugs:
>>> -----------------
>>> .......
>>> Under Linux, select() may report a socket file descriptor as "ready for
>>> reading", while nevertheless a subsequent read blocks. This could for
>>> example happen when data has arrived but upon examination has wrong
>>> checksum and is discarded. There may be other circumstances in which a
>>> file descriptor is spuriously reported as ready.
>>> .......
>>
>> Det lyder nu mere som den modsatte udgave af det problem du sad med.
>
> Enig. Og iøvrigt står ovenstående ikke i "man 2 select" på mit system,
> så det kan være en gammel bug fra Linux-1.2 tiden...

Det står heller ikke i man 2 select på mit system.
Jeg skal ikke udtale mig om den side jeg henviser til er autorativ, men i og
med der bla. står:
pselect() was added to Linux in kernel 2.6.16
bemærk datid _was_ added, tror jeg ikke den er så gammel som du siger der.

> Havde det været
> et problem man render ind i, ville Linux være ubrugeligt til webservere
> og lignende.

Det er netop ikke et problem 'man render ind i', men noget der opstår, måske
1 ud af 100.000 gange.

Jeg prøver een gang til:
Er vi enige om, at
while select(....) = 1
På kun een fd og kun readfs bør returnere 1 når fd'en bliver readable ?
(incl close osv.)
Hvis ja, er vi så enige om at en efterfølgende recv vil returnere
data/0/fejl?
Hvis ja, er vi så enige om at den næste
while select(....) = 1
ikke burde blive sand ved en closed socket?

Problemet er, at select'en bliver _ved_ med at returnere _1_, hvor den
retteligt skulle have returneret 0 eller -1.

Og hvis det var muligt at reproducere fejlen, så ville man nok ikke skrive:
......
There may be other circumstances in which a file descriptor is spuriously
reported as ready
.....


--
Med venlig hilsen
Stig Johansen

Kent Friis (01-06-2008)
Kommentar
Fra : Kent Friis


Dato : 01-06-08 09:37

Den Sun, 01 Jun 2008 07:55:16 +0200 skrev Stig Johansen:
> Kent Friis wrote:
>
>> Den Sat, 31 May 2008 17:02:16 +0200 skrev Anders Wegge Jakobsen:
>>> Stig Johansen <wopr.dk@gmaill.com> writes:
>>>
>>>> Kent Friis wrote:
>>>>
>>>>> Hvor ser du bug'en?
>>>>
>>>> <http://linux.die.net/man/2/select>
>>>>
>>>> Overskrift Bugs:
>>>> -----------------
>>>> .......
>>>> Under Linux, select() may report a socket file descriptor as "ready for
>>>> reading", while nevertheless a subsequent read blocks. This could for
>>>> example happen when data has arrived but upon examination has wrong
>>>> checksum and is discarded. There may be other circumstances in which a
>>>> file descriptor is spuriously reported as ready.
>>>> .......
>>>
>>> Det lyder nu mere som den modsatte udgave af det problem du sad med.
>>
>> Enig. Og iøvrigt står ovenstående ikke i "man 2 select" på mit system,
>> så det kan være en gammel bug fra Linux-1.2 tiden...
>
> Det står heller ikke i man 2 select på mit system.
> Jeg skal ikke udtale mig om den side jeg henviser til er autorativ, men i og
> med der bla. står:
> pselect() was added to Linux in kernel 2.6.16
> bemærk datid _was_ added, tror jeg ikke den er så gammel som du siger der.

Det var kun et gæt.

>> Havde det været
>> et problem man render ind i, ville Linux være ubrugeligt til webservere
>> og lignende.
>
> Det er netop ikke et problem 'man render ind i', men noget der opstår, måske
> 1 ud af 100.000 gange.

På en travl webserver er 1 ud af 100.000 gange indenfor det næste
minut.

> Jeg prøver een gang til:
> Er vi enige om, at
> while select(....) = 1
> På kun een fd og kun readfs bør returnere 1 når fd'en bliver readable ?
> (incl close osv.)
> Hvis ja, er vi så enige om at en efterfølgende recv vil returnere
> data/0/fejl?

Ja, men det checkede du ikke på.

> Hvis ja, er vi så enige om at den næste
> while select(....) = 1
> ikke burde blive sand ved en closed socket?

Du kan ikke select'e på en socket efter du har kaldt close().

Hvis den anden ende har kaldt close(), vil select blive ved med at være
sand, og recv blive ved med at returnere 0 (EOF) indtil du reagerer på
det.

> Problemet er, at select'en bliver _ved_ med at returnere _1_, hvor den
> retteligt skulle have returneret 0 eller -1.

Nej, i førnævnte eksempel skal den netop blive ved med at returnere 1.

> Og hvis det var muligt at reproducere fejlen, så ville man nok ikke skrive:
> .....
> There may be other circumstances in which a file descriptor is spuriously
> reported as ready
> ....

Korrekt, men jeg har stadig ikke set noget der tyder på at det er den
bug du er rendt ind i. Efter din beskrivelse opfører select() og
recv() sig korrekt.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 18:05

Kent Friis wrote:

> Hvis den anden ende har kaldt close(), vil select blive ved med at være
> sand, og recv blive ved med at returnere 0 (EOF) indtil du reagerer på
> det.

Hvis det er sådan det er under Linux, så er det sådan det er.
Jeg har dog ikke kunnet genskabe det med telnet og utidig close.

Det undrer mig dog, at man så tilsyneladende ikke kan bruge select som
eventhandler under Linux.

--
Med venlig hilsen
Stig Johansen

Kent Friis (01-06-2008)
Kommentar
Fra : Kent Friis


Dato : 01-06-08 19:14

Den Sun, 01 Jun 2008 19:05:27 +0200 skrev Stig Johansen:
> Kent Friis wrote:
>
>> Hvis den anden ende har kaldt close(), vil select blive ved med at være
>> sand, og recv blive ved med at returnere 0 (EOF) indtil du reagerer på
>> det.
>
> Hvis det er sådan det er under Linux, så er det sådan det er.

Sådan er det på *nix.

> Jeg har dog ikke kunnet genskabe det med telnet og utidig close.

Det kræver jo at den står netop i den løkke. Et lille test-program
der altid læser sådan burde hurtigt kunne bevise det.

> Det undrer mig dog, at man så tilsyneladende ikke kan bruge select som
> eventhandler under Linux.

select() returnerer kun hvilke fd'er der kan læses fra/skrives til.
Om det derefter er EOF der læses, fortæller select ikke noget om. Det
er ikke dens opgave.

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Peter Makholm (31-05-2008)
Kommentar
Fra : Peter Makholm


Dato : 31-05-08 09:03

Stig Johansen <wopr.dk@gmaill.com> writes:

> I og med selecten angiver at der er data ready, havde jeg ikke testet på den
> efterfølgende recv.

SUSv3 siger ellers følgende:

A descriptor shall be considered ready for reading when a call to
an input function with O_NONBLOCK clear would not block, whether
or not the function would transfer data successfully. (The
function might return data, an end-of-file indication, or an error
other than one indicating that it is blocked, and in each of these
cases the descriptor shall be considered ready for reading.)

Manualsiden i Linux fortæller det sammen lidt anderledes:

A file descriptor is considered ready if it is possible to perform
the corresponding I/O operation (e.g., read(2)) without blocking.

Så at select returnerer et filehandle betyder hverken mere eller
mindre end at et kald til read/recv/... ikke vil blokkere. Det vil på
ingen måde garantere dig hvilken type resultat du får.

> Der er tilsyneladende omstændigheder, hvor en select melder receive ready i
> det uendelige, uagtet af recv melder 0 eller fejl.

Ja, det fremgår klart af begge ovenstående stykker
dokumentation. Select virker altså både som dokumenteret i
systemdokumentationen og som defineret i den standard Linux primært
forsøger at implementere.

//Makholm

Stig Johansen (31-05-2008)
Kommentar
Fra : Stig Johansen


Dato : 31-05-08 15:45

Peter Makholm wrote:

> Ja, det fremgår klart af begge ovenstående stykker
> dokumentation. Select virker altså både som dokumenteret i
> systemdokumentationen og som defineret i den standard Linux primært
> forsøger at implementere.

Ja, men hvis man kigger på denne her:
<http://linux.die.net/man/2/select>

Overskrift Bugs:
-----------------
........
Under Linux, select() may report a socket file descriptor as "ready for
reading", while nevertheless a subsequent read blocks. This could for
example happen when data has arrived but upon examination has wrong
checksum and is discarded. There may be other circumstances in which a file
descriptor is spuriously reported as ready.
........

Så står det lidt anderledes.

--
Med venlig hilsen
Stig Johansen

Peter Makholm (01-06-2008)
Kommentar
Fra : Peter Makholm


Dato : 01-06-08 11:35

Stig Johansen <wopr.dk@gmaill.com> writes:

> Hvis ja, er vi så enige om at den næste
> while select(....) = 1
> ikke burde blive sand ved en closed socket?

Hvorfor forventer du at recv() vil blokerer hvis den anden ende har
lukket forbindelsen? Det lyder som en højst uhensigtsmæøssig
opførelse?

//Makholm

Adam Sjøgren (01-06-2008)
Kommentar
Fra : Adam Sjøgren


Dato : 01-06-08 13:15

On Sun, 01 Jun 2008 07:55:16 +0200, Stig wrote:

> Jeg prøver een gang til:
> Er vi enige om, at
> while select(....) = 1
> På kun een fd og kun readfs bør returnere 1 når fd'en bliver readable ?
> (incl close osv.)
> Hvis ja, er vi så enige om at en efterfølgende recv vil returnere
> data/0/fejl?
> Hvis ja, er vi så enige om at den næste
> while select(....) = 1
> ikke burde blive sand ved en closed socket?

Det er den sidste påstand du ikke har belæg for. recv() returnerer 0 på
en lukket forbindelse, uanset om du har kaldt recv() og fået 0 tilbage
på forbindelsen tidligere.

> Problemet er, at select'en bliver _ved_ med at returnere _1_, hvor den
> retteligt skulle have returneret 0 eller -1.

Kun hvis efterfølgende I/O blokerer (0), eller der er en fejl (-1).

recv() returnerer 0 med det samme for en lukket forbindelse - den
blokerer ikke efter første gang du har fået 0 tilbage, altså returnerer
select() ikke 0, da recv() ikke blokerer.

> Og hvis det var muligt at reproducere fejlen, så ville man nok ikke skrive:
> .....
> There may be other circumstances in which a file descriptor is spuriously
> reported as ready
> ....

Du blander to ting sammen: den fejl der omtales der, er hvor select() en
gang i mellem returnerer sand _selvom_ en efterfølgende I/O operation
blokerer.

Dit tilfælde er så at sige det modsatte (du forventer at I/O operationen
blokerer og at select() derfor burde returnere 0, men I/O operationen
blokerer ikke, og select() returnerer derfor en positiv værdi).


Mvh.

--
"Sprecken Sie deutsch, baby" Adam Sjøgren
asjo@koldfront.dk

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 15:50

Adam Sjøgren wrote:

> On Sun, 01 Jun 2008 07:55:16 +0200, Stig wrote:
>> Hvis ja, er vi så enige om at den næste
>> while select(....) = 1
>> ikke burde blive sand ved en closed socket?
>
> Det er den sidste påstand du ikke har belæg for. recv() returnerer 0 på
> en lukket forbindelse, uanset om du har kaldt recv() og fået 0 tilbage
> på forbindelsen tidligere.

Jeg er ikke ude på nogen påstand, kun at (prøve på) få tingene til også at
virke under Linux.

>> Problemet er, at select'en bliver _ved_ med at returnere _1_, hvor den
>> retteligt skulle have returneret 0 eller -1.
>
> Kun hvis efterfølgende I/O blokerer (0), eller der er en fejl (-1).
>
> recv() returnerer 0 med det samme for en lukket forbindelse - den
> blokerer ikke efter første gang du har fået 0 tilbage, altså returnerer
> select() ikke 0, da recv() ikke blokerer.

Det samme gør den under Windows, men kun een gang. Jeg ville forvente, at en
efterfølgende select og/eller recv ville returnere -1, men sådan er der jo
så meget.

>
>> Og hvis det var muligt at reproducere fejlen, så ville man nok ikke
>> skrive: .....
>> There may be other circumstances in which a file descriptor is spuriously
>> reported as ready
>> ....
>
> Du blander to ting sammen: den fejl der omtales der, er hvor select() en
> gang i mellem returnerer sand _selvom_ en efterfølgende I/O operation
> blokerer.

Muligvis, men jeg læser det som 2 separate fejl, den ene, som du selv
skriver:
..........
Under Linux, select() may report a socket file descriptor as "ready for
reading", while nevertheless a subsequent read blocks. This could for
example happen when data has arrived but upon examination has wrong
checksum and is discarded.
..........
Hvorimod jeg opfatter denne:
..........
There may be other circumstances in which a file descriptor is spuriously
reported as ready
..........
Som en separat, observeret, men endnu ikke identificeret/reproduceret fejl.

--
Med venlig hilsen
Stig Johansen

Adam Sjøgren (01-06-2008)
Kommentar
Fra : Adam Sjøgren


Dato : 01-06-08 16:16

On Sun, 01 Jun 2008 16:49:35 +0200, Stig wrote:

> Adam Sjøgren wrote:

>> recv() returnerer 0 med det samme for en lukket forbindelse - den
>> blokerer ikke efter første gang du har fået 0 tilbage, altså returnerer
>> select() ikke 0, da recv() ikke blokerer.

> Det samme gør den under Windows, men kun een gang.

Hvad får du anden gang under Windows? Og hvad siger dokumentationen til
Windows at der skal ske anden gang?

> Jeg ville forvente, at en efterfølgende select og/eller recv ville
> returnere -1, men sådan er der jo så meget.

Tjah, dokumentationen stemmer overens med hvad der sker. Om det så er
hvad man forventer eller ej, er en anden sag


Mvh.

--
"It is a sort of cheap and cheerful kind of Adam Sjøgren
abstraction, but it works well in practise." asjo@koldfront.dk

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 16:40

Adam Sjøgren wrote:

> Hvad får du anden gang under Windows?

Der er ingen 'anden gang' under Windows, eller hvad du spørger om ?
Der er tale om at læse en request i x antal bidder afhængig af
bufferstørrelse.

> Og hvad siger dokumentationen til
> Windows at der skal ske anden gang?

Grundkoden er fra ca. 2002, og jeg husker faktisk ikke detaljer om
dokumentation.
Den slags ting foregår primært via erfaringsudveksling i Borland grupperne.

>> Jeg ville forvente, at en efterfølgende select og/eller recv ville
>> returnere -1, men sådan er der jo så meget.
>
> Tjah, dokumentationen stemmer overens med hvad der sker. Om det så er
> hvad man forventer eller ej, er en anden sag

Det er jo som man læser dokumenationen, jeg opfatter eksempelvis denne her
fra man 2 select (under Errors):
.......
An invalid file descriptor was given in one of the sets. (Perhaps a file
descriptor that was already closed, or one on which an error has occurred.)
.......

Som en dokumentation af, at select på en 'closed' burde returnere -1, men
det afhænger vel af øjnene der ser.


--
Med venlig hilsen
Stig Johansen

Kent Friis (01-06-2008)
Kommentar
Fra : Kent Friis


Dato : 01-06-08 19:06

Den Sun, 01 Jun 2008 17:40:02 +0200 skrev Stig Johansen:
>>
>> Tjah, dokumentationen stemmer overens med hvad der sker. Om det så er
>> hvad man forventer eller ej, er en anden sag
>
> Det er jo som man læser dokumenationen, jeg opfatter eksempelvis denne her
> fra man 2 select (under Errors):
> ......
> An invalid file descriptor was given in one of the sets. (Perhaps a file
> descriptor that was already closed, or one on which an error has occurred.)
> ......
>
> Som en dokumentation af, at select på en 'closed' burde returnere -1, men
> det afhænger vel af øjnene der ser.

Med "a file descriptor that was already closed" menes:

close(fd);
select(... fd ...);

Altså at man selv har lukket den. Så er den naturligvis ikke gyldig
længere.

Hvorimod når modparten har lukket den, returnerer select at der
kan læses, og den efterfølgende recv() vil returnere 0 (ingen data).
Og læser man igen, vil den igen returnere 0 (stadig ingen data).

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Adam Sjøgren (01-06-2008)
Kommentar
Fra : Adam Sjøgren


Dato : 01-06-08 17:04

On Sun, 01 Jun 2008 17:40:02 +0200, Stig wrote:

> Adam Sjøgren wrote:
>> Hvad får du anden gang under Windows?

> Der er ingen 'anden gang' under Windows, eller hvad du spørger om ?

Du siger at du forventer at select() og/eller recv() returnerer -1 efter
at recv() har returneret 0 en gang.

Det der sker under Linux er at recv() returnerer 0 når forbindelsen er
lukket og fortsætter med det uanset hvor mange gange du kalder recv()
herefter.

Jeg spørger om a) hvad der sker under Windows, siden dine forventninger
er anderledes end dokumentationen under Linux og b) Hvad dokumentationen
på Windows siger (siger den at select() og/eller recv() skal returnere
-1 hvis man select'er på en socket der er lukket?)

Med andre ord spørger jeg om om dokumentationen er forskellig eller om
det alene er den observerbare opførsel.

> Der er tale om at læse en request i x antal bidder afhængig af
> bufferstørrelse.

Jeg troede det handlede om at du mener at select() på Linux returnerer
noget forkert når recv() har returneret 0.

>> Og hvad siger dokumentationen til Windows at der skal ske anden gang?

> Grundkoden er fra ca. 2002, og jeg husker faktisk ikke detaljer om
> dokumentation.
> Den slags ting foregår primært via erfaringsudveksling i Borland grupperne.

Ok.

Så du forventer at systemkald under Linux opfører sig anderledes end
hvad dokumentationen siger, ikke fordi tilsvarende dokumentation under
det system du er vant til siger noget andet, men fordi det plejer at
virke sådan på det system?

> Det er jo som man læser dokumenationen, jeg opfatter eksempelvis denne her
> fra man 2 select (under Errors):

> ......
> An invalid file descriptor was given in one of the sets. (Perhaps a file
> descriptor that was already closed, or one on which an error has occurred.)
> ......

> Som en dokumentation af, at select på en 'closed' burde returnere -1, men
> det afhænger vel af øjnene der ser.

Absolut.

For mig at se indeholder ERRORS afsnittet en liste over de mulige
fejlværdier du kan få i errno _når_ returværdien er -1.


Mvh.

--
"Though this doesn't mean changing my sense of Adam Sjøgren
beauty. I.e., I don't like it." asjo@koldfront.dk

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 19:00

Adam Sjøgren wrote:

> On Sun, 01 Jun 2008 17:40:02 +0200, Stig wrote:
>
>> Adam Sjøgren wrote:
>>> Hvad får du anden gang under Windows?
>
>> Der er ingen 'anden gang' under Windows, eller hvad du spørger om ?
>
> Du siger at du forventer at select() og/eller recv() returnerer -1 efter
> at recv() har returneret 0 en gang.

Nærmere, at jeg forventer at select() returnerer -1 på en closed socket.

> Det der sker under Linux er at recv() returnerer 0 når forbindelsen er
> lukket og fortsætter med det uanset hvor mange gange du kalder recv()
> herefter.

Det har jeg ikke afprøvet, hverken under Windows eller Linux. Jeg snakker
kun om kombinationen select() + recv().

> Jeg spørger om a) hvad der sker under Windows,

Der virker det, eller har jeg bare ikke set fejlen?
Det der er interessant for mig er udnyttelsen af NPTL threads.
Under Linux/NPTL kan jeg sagtens komme op på 300+ samtidige requests på en
PII 200MHz.
Den performance kan jeg slet ikke komme op på under Windows, så der er ikke
ikke mulighed for at afprøve tilsvarende belastnnger.

> siden dine forventninger
> er anderledes end dokumentationen under Linux og b) Hvad dokumentationen
> på Windows siger (siger den at select() og/eller recv() skal returnere
> -1 hvis man select'er på en socket der er lukket?)
>
> Med andre ord spørger jeg om om dokumentationen er forskellig eller om
> det alene er den observerbare opførsel.

Dokumentationen ligger i en hjælpefil på min Windows maskine, så jeg kan
ikke klippe klistre.
Men bortset fra at nfds bliver ignoret, en af de 3 fds'er _skal_ være
udfyldt, andre felkode osv., så står der im grossen træk det samme.

Der står ingen steder, at select() på en closed socket _skal_ returnere -1,
heller ikke det modsatte, så det må vi bogføre under mine
forventninger/observeret opførsel.

>> Der er tale om at læse en request i x antal bidder afhængig af
>> bufferstørrelse.
>
> Jeg troede det handlede om at du mener at select() på Linux returnerer
> noget forkert når recv() har returneret 0.

Jeg vil til enhver tid mene, at hvis select() bliver ved med at returnere 1
på en closed socket, så er det forkert.
Men det er min _mening_, hvis det er 'as designed', så er jeg bare ikke
enige med 'designeren'.

> Så du forventer at systemkald under Linux opfører sig anderledes end
> hvad dokumentationen siger, ikke fordi tilsvarende dokumentation under
> det system du er vant til siger noget andet, men fordi det plejer at
> virke sådan på det system?

Jeg forventer ikke at Linux opfører sig præcist som Windows. Som nævnt
ovenfor, så der der nogle ting, der er ligegyldige under Windows, men har
betydning under Linux.

>> Det er jo som man læser dokumenationen, jeg opfatter eksempelvis denne
>> her fra man 2 select (under Errors):
>
>> ......
>> An invalid file descriptor was given in one of the sets. (Perhaps a file
>> descriptor that was already closed, or one on which an error has
>> occurred.) ......
>
>> Som en dokumentation af, at select på en 'closed' burde returnere -1, men
>> det afhænger vel af øjnene der ser.
>
> Absolut.
>
> For mig at se indeholder ERRORS afsnittet en liste over de mulige
> fejlværdier du kan få i errno _når_ returværdien er -1.

Enig, men man kunne slutte modsætningsvist, at hvis en given fejl består, så
_skal_ den returnere -1.

--
Med venlig hilsen
Stig Johansen

Kent Friis (01-06-2008)
Kommentar
Fra : Kent Friis


Dato : 01-06-08 19:23

Den Sun, 01 Jun 2008 20:00:28 +0200 skrev Stig Johansen:
> Adam Sjøgren wrote:
>
>> On Sun, 01 Jun 2008 17:40:02 +0200, Stig wrote:
>>
>>> Adam Sjøgren wrote:
>>>> Hvad får du anden gang under Windows?
>>
>>> Der er ingen 'anden gang' under Windows, eller hvad du spørger om ?
>>
>> Du siger at du forventer at select() og/eller recv() returnerer -1 efter
>> at recv() har returneret 0 en gang.
>
> Nærmere, at jeg forventer at select() returnerer -1 på en closed socket.

Den er kun closed i den anden ende. Du har ikke kaldt close endnu.
Derfor bliver recv ved med at returnere 0 = EOF.

Præcis som med enhver anden fil.

>> Jeg spørger om a) hvad der sker under Windows,
>
> Der virker det, eller har jeg bare ikke set fejlen?
> Det der er interessant for mig er udnyttelsen af NPTL threads.
> Under Linux/NPTL kan jeg sagtens komme op på 300+ samtidige requests på en
> PII 200MHz.
> Den performance kan jeg slet ikke komme op på under Windows, så der er ikke
> ikke mulighed for at afprøve tilsvarende belastnnger.

Hvad select returnerer har intet med belastning at gøre. Hvis belastning
gør en forskel i dit program, må det skyldes at dit program sjældent
står i den løkke problemet forekommer i ret længe, og at det derfor
er sjældent at modparten lukker forbindelsen i det øjeblik.

Et testprogram der konstant står i den løkke vil give select=1 og
recv=0 fra det øjeblik modparten lukker forbindelsen uanset belastning
og uanset brug af threads.

> Jeg vil til enhver tid mene, at hvis select() bliver ved med at returnere 1
> på en closed socket, så er det forkert.
> Men det er min _mening_, hvis det er 'as designed', så er jeg bare ikke
> enige med 'designeren'.

Så kender du ikke til unix-filosofien. "Everything is a file", det
gælder også netværks-forbindelser. Læser man til enden af en
normal fil, så returnerer den også EOF lige så længe man gider
blive ved med at læse. (Og jo, man kan sagtens bruge read() på
en netværksforbindelse, man behæver slet ikke recv(). Eller stdio
for den sags skyld selvom manualen vistnok fraråder det).

Mvh
Kent
--
"So there I was surrounded by all these scary creatures
They were even scarier than what Microsoft call features"
- C64Mafia: Forbidden Forest (Don't Go Walking Slow).

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 19:54

Kent Friis wrote:

>> Nærmere, at jeg forventer at select() returnerer -1 på en closed socket.
>
> Den er kun closed i den anden ende. Du har ikke kaldt close endnu.
> Derfor bliver recv ved med at returnere 0 = EOF.

Ok.

> Et testprogram der konstant står i den løkke vil give select=1 og
> recv=0 fra det øjeblik modparten lukker forbindelsen uanset belastning
> og uanset brug af threads.

Jeg er sikker på jeg prøvede med at telnette, skrive et par tegn, og
derefter afbryde/lukke.
Det burde fremprovokere det samme, men det kan godt være jeg husker forkert.

> Så kender du ikke til unix-filosofien. "Everything is a file", det
> gælder også netværks-forbindelser.

Mit favorit OS, MPE/iX har/havde samme filosofi.
Derudover havde man derudover noget der hed file equations, hvor man globalt
for sessions/batchjobs kunne redirigere de logiske navne til alle mulige
slags 'filer'.

> Læser man til enden af en
> normal fil, så returnerer den også EOF lige så længe man gider
> blive ved med at læse. (Og jo, man kan sagtens bruge read() på
> en netværksforbindelse, man behæver slet ikke recv(). Eller stdio
> for den sags skyld selvom manualen vistnok fraråder det).

Det er så anderledes i forhold til min verden. Jeg er vant til at EOF
returneres een, og kun een gang, og efterfølgende read's vil fejle.
(med mindre der er tale om message queues).

--
Med venlig hilsen
Stig Johansen

Stig Johansen (01-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 01-06-08 20:43

Stig Johansen wrote:

> Adam Sjøgren wrote:
>
>> Jeg spørger om a) hvad der sker under Windows,
>
> Der virker det, eller har jeg bare ikke set fejlen?

Nu har jeg lige prøvet at lægge lidt 'ting' ind, og singlesteppet ovre på
Windows.

Der sker det, at select()'en returnerer 0, og ikke -1 efter den
specificerede timeout, når jeg afbryder 'den anden ende'.

Jeg kan desværre ikke gøre det samme på Linux.

--
Med venlig hilsen
Stig Johansen

Peter Makholm (02-06-2008)
Kommentar
Fra : Peter Makholm


Dato : 02-06-08 05:46

Stig Johansen <wopr.dk@gmaill.com> writes:

> Der sker det, at select()'en returnerer 0, og ikke -1 efter den
> specificerede timeout, når jeg afbryder 'den anden ende'.

Så det du siger er at et recv() kald i windows vil blokere selvom
windows har fået at vide fra den anden side at der ikke kommer flere
data?

Det lyder uhensigtsmæssigt. Det burde slet ikke være nødvendigt at
vente en timeouts tid når den anden ende fortælle at der ikke er
yderligere data, det er en hændelse der kan håndteres med det samme.

//Makholm

Stig Johansen (02-06-2008)
Kommentar
Fra : Stig Johansen


Dato : 02-06-08 06:35

Peter Makholm wrote:

> Stig Johansen <wopr.dk@gmaill.com> writes:
>
>> Der sker det, at select()'en returnerer 0, og ikke -1 efter den
>> specificerede timeout, når jeg afbryder 'den anden ende'.
>
> Så det du siger er at et recv() kald i windows vil blokere selvom
> windows har fået at vide fra den anden side at der ikke kommer flere
> data?

Det det rent faktisk skete er at jeg har sendt 19 bytes fra en telnet og
derefter afbrudt.
Jeg starter med at læse 10 bytes i en recv for check af diverse ting.
jeg har så (pseudokode)
while select(..) = 1
bufflen := recv(...)
Selecten returnerer 1, og bufflen returnerer 9 bytes, som bliver tilføjet
bufferen.
Næste select i whilen returnere så 0 (=timeout), og dermed er while loopet
færdigt.
Der blev hverken triggeret en close/reset eller en recv på 0 - intet.

> Det lyder uhensigtsmæssigt.

Windows og hensigtsmæssigt er måske ikke 2 ord man skal bruge i samme
sætning.

> Det burde slet ikke være nødvendigt at
> vente en timeouts tid når den anden ende fortælle at der ikke er
> yderligere data, det er en hændelse der kan håndteres med det samme.

Enig, men herrens og Williams veje er uransagelige.
Som jeg visnok skrev, så er mange windows 'ting' lavet, og baseret på
gensidige erfaringsudvekslinger, og ikke kun dokumentationen.

I det her tilfælde _står_ der direkte i Windows hjælpefilen/dokumentationen,
at en select vil returnere ready ved en connection closed/reset, men den
gør det bare _ikke_ (på min Windows 2000 Pro).

--
Med venlig hilsen
Stig Johansen

Søg
Reklame
Statistik
Spørgsmål : 177547
Tips : 31968
Nyheder : 719565
Indlæg : 6408797
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste