9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
@ 2014-11-13 12:21 Pavel Klinkovský
  2014-11-13 12:43 ` cinap_lenrek
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 12:21 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

Hi all,

I am trying such simple program:

#include <u.h>
#include <libc.h>

static void
closer(int dfd) {
print("closer(%d): 1\n", getpid());
sleep(10 * 1000);
print("closer(%d): 2\n", getpid());
close(dfd);
print("closer(%d): 3\n", getpid());
}

void
main(int, char**)
{
int dfd;
char ddir[NETPATHLEN];
char buf[1024];
long nr;

print("main  (%d): 1\n", getpid());
dfd = dial("tcp!192.168.8.61!23", nil, ddir, nil);
if (dfd < 0)
sysfatal("dial: %r");

print("main  (%d): 2\n", getpid());
switch (rfork(RFPROC|RFREND|RFMEM)) {
case -1:
sysfatal("fork: %r");

case 0:
closer(dfd);
break;

default:
for (;;) {
print("main  (%d): 3\n", getpid());
nr = read(dfd, buf, sizeof buf);
print("main  (%d): 4\n", getpid());
if (nr <= 0)
break;
}

print("main  (%d): 5\n", getpid());
close(dfd);
break;
}

exits(nil);
}

I want to have one process waiting in 'read' function on opened TCP
connection.
I want to close such a TCP connection from another process (created with
shared file descriptor table).
I would expect that 'read' function is finished with -1...
...but it is not.

Here is the output of the program:
main  (11112): 1
main  (11112): 2
closer(11113): 1
main  (11112): 3
main  (11112): 4
main  (11112): 3
closer(11113): 2
closer(11113): 3

You can see that 'main' process is still pending in 'read' function on
already closed 'fd'.

Do I really have to use notes to release the pending 'main' in 'read' call?

Pavel

[-- Attachment #2: Type: text/html, Size: 4066 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 12:21 [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'? Pavel Klinkovský
@ 2014-11-13 12:43 ` cinap_lenrek
  2014-11-13 12:49   ` Pavel Klinkovský
  0 siblings, 1 reply; 12+ messages in thread
From: cinap_lenrek @ 2014-11-13 12:43 UTC (permalink / raw)
  To: 9fans

closing the filedescriptor just removes one reference to the channel
from the descriptor table. the kernels read() function takes its
own reference to the channel to make sure it doesnt go away under it.

the method you describe is a anti-pattern. because the filedescript
(slot) can be reallocated. so even if you close it in the proc, the
fd slot could be reused for somthing different before the other proc
comes arround reading it (or worse, writing it).

what you want is to hangup the tcp connection without fiddling with
the filedescriptor table. this can be done by writing "hangup" to the
connections ctl file like:

int fd, cfd;

fd = dial("tcp!....!123", nil, nil, &cfd);

.....


hangup(cfd);	/* hangup connection, fd stays valid but i/o will error */

--
cinap



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 12:43 ` cinap_lenrek
@ 2014-11-13 12:49   ` Pavel Klinkovský
  2014-11-13 13:08     ` cinap_lenrek
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 12:49 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

Hi cinap,

hangup(cfd);    /* hangup connection, fd stays valid but i/o will error */
>

thank you for your explanation and help.

Going to use 'hangup' function. ;)

Pavel

[-- Attachment #2: Type: text/html, Size: 484 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 12:49   ` Pavel Klinkovský
@ 2014-11-13 13:08     ` cinap_lenrek
  2014-11-13 13:13       ` Pavel Klinkovský
  0 siblings, 1 reply; 12+ messages in thread
From: cinap_lenrek @ 2014-11-13 13:08 UTC (permalink / raw)
  To: 9fans

another way to implement these kinds of timeouts is
alarm(), see sleep(2).

--
cinap



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 13:08     ` cinap_lenrek
@ 2014-11-13 13:13       ` Pavel Klinkovský
  2014-11-13 13:17         ` cinap_lenrek
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 13:13 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

> another way to implement these kinds of timeouts is
> alarm(), see sleep(2).
>

Yes, I know.

But it was just a simplified example to explain my real need:
- 'receiver' process
- another 'sender' process, which should have a possibility to close the
TCP connection, and relase 'receiver' from read() call...

Pavel

[-- Attachment #2: Type: text/html, Size: 654 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 13:13       ` Pavel Klinkovský
@ 2014-11-13 13:17         ` cinap_lenrek
  2014-11-13 13:20           ` Pavel Klinkovský
  0 siblings, 1 reply; 12+ messages in thread
From: cinap_lenrek @ 2014-11-13 13:17 UTC (permalink / raw)
  To: 9fans

ah, ok :)

--
cinap



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 13:17         ` cinap_lenrek
@ 2014-11-13 13:20           ` Pavel Klinkovský
  2014-11-13 13:37             ` cinap_lenrek
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 13:20 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

OTOH, 'hangup' approach does not work in UDP.
It means, read() is not finished... :(

Pavel

2014-11-13 14:17 GMT+01:00 <cinap_lenrek@felloff.net>:

> ah, ok :)
>
> --
> cinap
>
>

[-- Attachment #2: Type: text/html, Size: 542 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 13:20           ` Pavel Klinkovský
@ 2014-11-13 13:37             ` cinap_lenrek
  2014-11-13 13:45               ` Pavel Klinkovský
  0 siblings, 1 reply; 12+ messages in thread
From: cinap_lenrek @ 2014-11-13 13:37 UTC (permalink / raw)
  To: 9fans

interesting, that might be worth implementing.

the alternative would be to send the reading process a note to
interrupt the blocking syscall.

the closer proc should just send the note and not close the fd.
and the reader proc should close the fd once he's out of the
reading loop.

--
cinap



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 13:37             ` cinap_lenrek
@ 2014-11-13 13:45               ` Pavel Klinkovský
  2014-11-13 14:43                 ` cinap_lenrek
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 13:45 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

> interesting, that might be worth implementing.
>

Maybe.


> the alternative would be to send the reading process a note to
> interrupt the blocking syscall.
>

Actually, it my 'plan B'... ;)

the closer proc should just send the note and not close the fd.
> and the reader proc should close the fd once he's out of the
> reading loop.
>

Exactly!

Well, I would prefer a solution with 'hangup', it seems cleaner to me...
...but since it is not implemented in UDP driver, I will implement the note
based solution.

Pavel


Pavel

[-- Attachment #2: Type: text/html, Size: 1188 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 13:45               ` Pavel Klinkovský
@ 2014-11-13 14:43                 ` cinap_lenrek
  2014-11-13 14:50                   ` Pavel Klinkovský
  0 siblings, 1 reply; 12+ messages in thread
From: cinap_lenrek @ 2014-11-13 14:43 UTC (permalink / raw)
  To: 9fans

the changes to implement udp hangup are trivial tho:

diff -r 51564dc1adae sys/src/9/ip/udp.c
--- a/sys/src/9/ip/udp.c	Thu Nov 13 10:23:53 2014 +0100
+++ b/sys/src/9/ip/udp.c	Thu Nov 13 15:42:24 2014 +0100
@@ -518,6 +518,11 @@

 	ucb = (Udpcb*)c->ptcl;
 	if(n == 1){
+		if(strcmp(f[0], "hangup") == 0){
+			qhangup(c->rq, nil);
+			qhangup(c->wq, nil);
+			return nil;
+		}
 		if(strcmp(f[0], "headers") == 0){
 			ucb->headers = 7;	/* new headers format */
 			return nil;

--
cinap



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 14:43                 ` cinap_lenrek
@ 2014-11-13 14:50                   ` Pavel Klinkovský
  2014-11-13 15:35                     ` Pavel Klinkovský
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 14:50 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

> the changes to implement udp hangup are trivial tho:
>
> diff -r 51564dc1adae sys/src/9/ip/udp.c
> --- a/sys/src/9/ip/udp.c        Thu Nov 13 10:23:53 2014 +0100
> +++ b/sys/src/9/ip/udp.c        Thu Nov 13 15:42:24 2014 +0100
> @@ -518,6 +518,11 @@
>
>         ucb = (Udpcb*)c->ptcl;
>         if(n == 1){
> +               if(strcmp(f[0], "hangup") == 0){
> +                       qhangup(c->rq, nil);
> +                       qhangup(c->wq, nil);
> +                       return nil;
> +               }
>

I see.
Going to try.

Pavel

[-- Attachment #2: Type: text/html, Size: 947 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'?
  2014-11-13 14:50                   ` Pavel Klinkovský
@ 2014-11-13 15:35                     ` Pavel Klinkovský
  0 siblings, 0 replies; 12+ messages in thread
From: Pavel Klinkovský @ 2014-11-13 15:35 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

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

> +               if(strcmp(f[0], "hangup") == 0){
>> +                       qhangup(c->rq, nil);
>> +                       qhangup(c->wq, nil);
>> +                       return nil;
>> +               }
>
>
You patch works as expected. ;)

Thanks.

Pavel

[-- Attachment #2: Type: text/html, Size: 951 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-11-13 15:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-13 12:21 [9fans] Doesn't 'close' call finish pending 'read' on the same 'fd'? Pavel Klinkovský
2014-11-13 12:43 ` cinap_lenrek
2014-11-13 12:49   ` Pavel Klinkovský
2014-11-13 13:08     ` cinap_lenrek
2014-11-13 13:13       ` Pavel Klinkovský
2014-11-13 13:17         ` cinap_lenrek
2014-11-13 13:20           ` Pavel Klinkovský
2014-11-13 13:37             ` cinap_lenrek
2014-11-13 13:45               ` Pavel Klinkovský
2014-11-13 14:43                 ` cinap_lenrek
2014-11-13 14:50                   ` Pavel Klinkovský
2014-11-13 15:35                     ` Pavel Klinkovský

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).