* about usage of `sigaction'
@ 2007-01-17 5:29 William Xu
2007-01-18 0:22 ` Kevin Ryde
0 siblings, 1 reply; 6+ messages in thread
From: William Xu @ 2007-01-17 5:29 UTC (permalink / raw)
[-- Attachment #1: Type: text/plain, Size: 993 bytes --]
Hi all,
i wrote a simple echo server/client. To catch SIGCHLD signal, i install
a signal handler before first `connect'. The problem is that when the
client exits, the handler seems not called. Instead, upon a new client
connected to the server, the handler will be called(due to last
client's exit).
To summarize,
,----[ first client ]
| $ guile -e main server.scm
| server started on localhost:10000
| New client(#(2 2130706433 54570)) incomming
|
| $ guile -e main client.scm
| connected to server
| hi
| hi
| \x04
| $
`----
,----[ second client ]
| $ guile -e main server.scm
| server started on localhost:10000
| New client(#(2 2130706433 47200)) incomming
| child 16648 terminated
| New client(#(2 2130706433 47201)) incomming
|
| $ guile -e main client.scm
| connected to server
| hey
| hey
| \x04
| $
`----
Can the signal handler be called as soon as the client exits?
Attchments are testing codes.
--
William
Work continues in this area.
-- DEC's SPR-Answering-Automaton
[-- Attachment #2: client.scm --]
[-- Type: text/plain, Size: 1531 bytes --]
;; echo client
(use-modules (ice-9 optargs))
(use-modules (ice-9 getopt-long))
(use-modules (ice-9 rdelim))
(define (hostname->ip hostname)
"Convert HOSTNAME to its IP.
e.g.,
(hostname->ip \"www.google.com\") => \"64.233.189.104\""
(inet-ntop AF_INET (car (hostent:addr-list (gethost hostname)))))
\f
(define (main args)
(let* ((option-spec '((help (single-char #\h) (value #f))
(host (single-char #\H) (value #t))
(port (single-char #\p) (value #t))))
(options (getopt-long args option-spec)))
(if (option-ref options 'help #f)
(usage)
(client (option-ref options 'host "localhost")
(option-ref options 'port "10000")))))
(define (usage)
(display "\
Usage: client.scm [OPTIONS]
-h, --help show this help
-H, --host=LOCALHOST remote address
-p, --port=10000 remote port
")
(exit 1))
(define (client host port)
(let ((s (socket PF_INET SOCK_STREAM 0))
(host-ip (hostname->ip host))
(port-value (string->number port)))
(connect s AF_INET (inet-pton AF_INET host-ip) port-value)
(display "connected to server\n")
(echo-loop s)))
(define (echo-loop server-port)
(let ((line (read-line (current-input-port) 'concat)))
(while (not (eof-object? line))
(display line server-port)
(display (read-line server-port 'concat))
(set! line (read-line (current-input-port) 'concat)))
(close server-port)))
;;; client.scm ends here
[-- Attachment #3: server.scm --]
[-- Type: text/plain, Size: 2371 bytes --]
;; echo server
(use-modules (ice-9 optargs))
(use-modules (ice-9 format))
(use-modules (ice-9 getopt-long))
(use-modules (ice-9 rdelim))
(define (hostname->ip hostname)
"Convert HOSTNAME to its IP.
e.g.,
(hostname->ip \"www.google.com\") => \"64.233.189.104\""
(inet-ntop AF_INET (car (hostent:addr-list (gethost hostname)))))
\f
(define (main args)
(let* ((option-spec '((help (single-char #\h) (value #f))
(host (single-char #\H) (value #t))
(port (single-char #\p) (value #t))))
(options (getopt-long args option-spec)))
(if (option-ref options 'help #f)
(usage)
(server (option-ref options 'host "localhost")
(option-ref options 'port "10000")))))
(define (usage)
(display "\
Usage: server.scm [OPTIONS]
-h, --help show this help
-H, --host=LOCALHOST listening address
-p, --port=10000 listening port
")
(exit 1))
(define (server host port)
(let* ((s (socket PF_INET SOCK_STREAM 0))
(host-ip (hostname->ip host))
(port-value (string->number port)))
(setsockopt s SOL_SOCKET SO_REUSEADDR 1)
(bind s AF_INET (inet-pton AF_INET host-ip) port-value)
(listen s 5)
(format #t "server started on ~a:~a\n" host port)
(sigaction SIGCHLD
(lambda (sig)
;; (let ((pid (car (waitpid -1 WNOHANG))))
;; (while (> pid 0)
;; (format #t "child ~d terminated\n" pid)
;; (set! pid (car (waitpid -1 WNOHANG)))))))
(format #t
"child ~d terminated\n"
(car (waitpid -1 WNOHANG)))))
(while #t
(let* ((client (accept s))
(client-port (car client)))
(format #t "New client(~S) incomming\n" (cdr client))
(and (zero? (primitive-fork)) ; child
(begin (close-port s)
(echo-loop client-port)
(primitive-exit)))
(close-port client-port)))))
(define (echo-loop port)
"Read from PORT and send back."
(let ((line (read-line port 'concat)))
(while (not (eof-object? line))
(display line port)
(set! line (read-line port 'concat)))
(close-port port)))
;;; server.scm ends here
[-- Attachment #4: Type: text/plain, Size: 140 bytes --]
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: about usage of `sigaction'
2007-01-17 5:29 about usage of `sigaction' William Xu
@ 2007-01-18 0:22 ` Kevin Ryde
2007-01-18 5:10 ` William Xu
0 siblings, 1 reply; 6+ messages in thread
From: Kevin Ryde @ 2007-01-18 0:22 UTC (permalink / raw)
Cc: guile-user
William Xu <william.xwl@gmail.com> writes:
>
> i wrote a simple echo server/client. To catch SIGCHLD signal, i install
> a signal handler before first `connect'. The problem is that when the
> client exits, the handler seems not called.
I expect you've checked with "ps" that the child has actually exited.
Otherwise I would wonder if the parent is stuck in accept, and doesn't
take the scheme level signal action until it returns.
I've had doubts about the timeliness of signal delivery in 1.8, but
haven't had a chance to look at it properly. (I tinkered with
SIGPIPE, it seemed to be delivered to the scheme level at a point a
couple of function calls later then the "display" or whatever that
provoked it. Perhaps some judiciously inserted SCM_TICKs would help.)
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: about usage of `sigaction'
2007-01-18 0:22 ` Kevin Ryde
@ 2007-01-18 5:10 ` William Xu
2007-01-18 22:55 ` Kevin Ryde
0 siblings, 1 reply; 6+ messages in thread
From: William Xu @ 2007-01-18 5:10 UTC (permalink / raw)
Kevin Ryde <user42@zip.com.au> writes:
> I expect you've checked with "ps" that the child has actually exited.
Yes, i think so.
,----[ ps -ef|grep serv ]
| william 12353 10420 0 12:54 pts/2 00:00:00 /home/william/bin/guile \ ./server.scm
| william 12364 12353 0 12:54 pts/2 00:00:00 [server.scm] <defunct>
| william 12379 12355 0 12:54 pts/3 00:00:00 grep serv
`----
> Otherwise I would wonder if the parent is stuck in accept, and doesn't
> take the scheme level signal action until it returns.
Yes, strace shows that server is stuck in accept. So all other things
are blocked during accept()? Maybe this is a problem of scheme accept?
--
William
Having wandered helplessly into a blinding snowstorm Sam was greatly
relieved to see a sturdy Saint Bernard dog bounding toward him with
the traditional keg of brandy strapped to his collar.
"At last," cried Sam, "man's best friend -- and a great big dog, too!"
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: about usage of `sigaction'
2007-01-18 5:10 ` William Xu
@ 2007-01-18 22:55 ` Kevin Ryde
2007-01-19 3:49 ` William Xu
0 siblings, 1 reply; 6+ messages in thread
From: Kevin Ryde @ 2007-01-18 22:55 UTC (permalink / raw)
Cc: guile-user
William Xu <william.xwl@gmail.com> writes:
>
> So all other things are blocked during accept()?
Signals for the thread in question at least :(.
> Maybe this is a problem of scheme accept?
It's not a good thing, though fixing it might be tricky.
Do you actually need to know immediately the child exits? Perhaps
it's enough to reap on the next connection. If you need to know then
you might keep a pipe open to each child, then `select' on them plus
the listening port. Whichever has some action (incoming connect or
exited child) can show up.
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: about usage of `sigaction'
2007-01-18 22:55 ` Kevin Ryde
@ 2007-01-19 3:49 ` William Xu
2007-01-22 0:52 ` Kevin Ryde
0 siblings, 1 reply; 6+ messages in thread
From: William Xu @ 2007-01-19 3:49 UTC (permalink / raw)
Kevin Ryde <user42@zip.com.au> writes:
> William Xu <william.xwl@gmail.com> writes:
>>
>> So all other things are blocked during accept()?
>
> Signals for the thread in question at least :(.
>
>> Maybe this is a problem of scheme accept?
>
> It's not a good thing, though fixing it might be tricky.
>
> Do you actually need to know immediately the child exits?
Currently it just makes me feel uncomfortable when it doesn't work as
expected.. I hope someday it could get fixed.
> Perhaps it's enough to reap on the next connection. If you need to
> know then you might keep a pipe open to each child, then `select' on
> them plus the listening port. Whichever has some action (incoming
> connect or exited child) can show up.
Yes, that could be a workaround. Thanks.
--
William
If the American dream is for Americans only, it will remain our dream
and never be our destiny.
-- Ren'\be de Visme Williamson
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: about usage of `sigaction'
2007-01-19 3:49 ` William Xu
@ 2007-01-22 0:52 ` Kevin Ryde
0 siblings, 0 replies; 6+ messages in thread
From: Kevin Ryde @ 2007-01-22 0:52 UTC (permalink / raw)
Cc: guile-user
William Xu <william.xwl@gmail.com> writes:
>
> Currently it just makes me feel uncomfortable when it doesn't work as
> expected.. I hope someday it could get fixed.
I'll add something like the following to the manual for a start, to at
least describe how it works now ...
Scheme code signal handlers are run via a system async (*note
System asyncs::), so they're called in the handler's thread at
the next safe opportunity. Generally this is after any
currently executing primitive procedure finishes (which could
be a long time for primitives that wait for an external
event).
Incidentally, if you just want to not create zombies among exited
children, apparently setting SIGCHLD to SIG_IGN works in current posix
(but not older systems).
--
"Party on contest winners, party on."
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-01-22 0:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-17 5:29 about usage of `sigaction' William Xu
2007-01-18 0:22 ` Kevin Ryde
2007-01-18 5:10 ` William Xu
2007-01-18 22:55 ` Kevin Ryde
2007-01-19 3:49 ` William Xu
2007-01-22 0:52 ` Kevin Ryde
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 read-only IMAP folder(s) and NNTP newsgroup(s).