Re: [Chicken-users] Pipe and thread problem

2012-10-25 Thread Aaron Patterson
On Thu, Oct 25, 2012 at 04:12:50AM -0400, Felix wrote:
> From: Moritz Heidkamp 
> Subject: Re: [Chicken-users] Pipe and thread problem
> Date: Wed, 24 Oct 2012 23:10:20 +0200
> 
> > Hey Chickeneers,
> > 
> > out of curiosity I implemented (probably horribly inefficitent)
> > thread-aware replacements for open-input-file* and open-output-file*
> > (see below). While implementing them I came across something that I
> > didn't quite understand: file-read and file-write raise errors whenever
> > the underlying syscall returns -1. However, in this case I want to
> > handle some error situations (i.e. EINTR, EAGAIN and EWOULDBLOCK). The
> > only way I could find to do this is by dispatching on (errno) in the
> > excpetion handler. However it looks like (errno) is not thread-safe so
> > it might actually return a different value when my handler is run. Is
> > this observation correct? Perhaps we should mention this in errno's
> > documentation? Also, to make it possible to handle these errors I
> > suggest to add the respective errno to the condition object. This would
> > be thread-safe as the posix unit declares disable-interrupts. Thoughts?
> 
> No, "errno" is not thread-safe. Posix-related errors (see "posix-error"
> in "posix-common.scm") get attached the error-string (obtained via
> strerror(3)), also adding errno would be fine, I'd say.
> 
> I'm quite sure "##sys#custom-input-port" and
> "##sys#custom-output-port" in "posixunix.scm" are alreay doing what
> you want, and much more efficiently.

I tried changing the program to use "##sys#custom-input-port", and the
program still froze.  Here is the version with "##sys#custom-input-port"
included:

(use srfi-18)
(use posix)

(define (produce writer)
  (thread-start!
(lambda ()
  (print "producer started")
  (let loop ((i 0))
(display (conc "hello" i " ") writer)
(newline writer)
(flush-output writer)
(thread-sleep! 1)
(loop (+ i 1))

(define (consume reader)
  (thread-start!
(lambda ()
  (print "consumer started")
  (let loop ()
(print (read-line reader))
(loop)

(define (stream-test in-fd out-fd)
  (let ((reader (##sys#custom-input-port "reader" "reader" in-fd))
(writer (##sys#custom-output-port "writer" "writer" out-fd)))
(produce writer)
(thread-join! (consume reader

(call-with-values create-pipe stream-test)

I tried the same program, but with Moritz's changes, and they seemed to
work.  The code is kind of long, so I posted it here:
  
  https://gist.github.com/3953900

-- 
Aaron Patterson
http://tenderlovemaking.com/

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-25 Thread Felix
From: Moritz Heidkamp 
Subject: Re: [Chicken-users] Pipe and thread problem
Date: Wed, 24 Oct 2012 23:10:20 +0200

> Hey Chickeneers,
> 
> out of curiosity I implemented (probably horribly inefficitent)
> thread-aware replacements for open-input-file* and open-output-file*
> (see below). While implementing them I came across something that I
> didn't quite understand: file-read and file-write raise errors whenever
> the underlying syscall returns -1. However, in this case I want to
> handle some error situations (i.e. EINTR, EAGAIN and EWOULDBLOCK). The
> only way I could find to do this is by dispatching on (errno) in the
> excpetion handler. However it looks like (errno) is not thread-safe so
> it might actually return a different value when my handler is run. Is
> this observation correct? Perhaps we should mention this in errno's
> documentation? Also, to make it possible to handle these errors I
> suggest to add the respective errno to the condition object. This would
> be thread-safe as the posix unit declares disable-interrupts. Thoughts?

No, "errno" is not thread-safe. Posix-related errors (see "posix-error"
in "posix-common.scm") get attached the error-string (obtained via
strerror(3)), also adding errno would be fine, I'd say.

I'm quite sure "##sys#custom-input-port" and
"##sys#custom-output-port" in "posixunix.scm" are alreay doing what
you want, and much more efficiently.


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Moritz Heidkamp
Hey Chickeneers,

out of curiosity I implemented (probably horribly inefficitent)
thread-aware replacements for open-input-file* and open-output-file*
(see below). While implementing them I came across something that I
didn't quite understand: file-read and file-write raise errors whenever
the underlying syscall returns -1. However, in this case I want to
handle some error situations (i.e. EINTR, EAGAIN and EWOULDBLOCK). The
only way I could find to do this is by dispatching on (errno) in the
excpetion handler. However it looks like (errno) is not thread-safe so
it might actually return a different value when my handler is run. Is
this observation correct? Perhaps we should mention this in errno's
documentation? Also, to make it possible to handle these errors I
suggest to add the respective errno to the condition object. This would
be thread-safe as the posix unit declares disable-interrupts. Thoughts?

OK, here we go. It seems to work with your program, Aaron:

(define (open-input-fd fd)
  (make-input-port
   (lambda ()
 (let loop ()
   (thread-wait-for-i/o! fd #:input)
   (or (condition-case
   (string-ref (car (file-read fd 1)) 0)
 (exn (exn i/o file)
  (select (errno)
((errno/intr errno/again errno/wouldblock)
 #f)
(else (signal exn)
   (loop
   (lambda ()
 (nth-value 0 (file-select fd #f 0)))
   (lambda ()
 (file-close fd

(define (open-output-fd fd)
  (let ((port (open-output-file* fd)))
(make-output-port
 (lambda (buffer)
   (let loop ((buffer buffer) (len (string-length buffer)))
 (thread-wait-for-i/o! fd #:output)
 (let ((written (condition-case
(file-write fd buffer)
  (exn (exn i/o file)
   (select (errno)
 ((errno/intr errno/again errno/wouldblock)
  #f)
 (else (signal exn)))
   (if written
   (unless (= written len)
 (loop (substring buffer written len) (- len written)))
   (loop buffer len)
 (lambda ()
   (close-output-port port))
 (lambda ()
   (flush-output port)

Oh yeah, and note the lame solution of opening the output FD with
open-output-file* -- this is only because there is no flush-file in
posix. Perhaps worth adding?

Moritz

Aaron Patterson  writes:

> On Wed, Oct 24, 2012 at 08:04:37AM -0400, Felix wrote:
>> From: Aaron Patterson 
>> Subject: [Chicken-users] Pipe and thread problem
>> Date: Tue, 23 Oct 2012 14:30:57 -0700
>> 
>> > Hi, I'm trying to simulate reading from a TTY that writes every two
>> > seconds.  I want to do this with a pipe and two threads, one thread
>> > writes every N seconds, while the other reads any data available on the
>> > pipe.
>> > 
>> > Unfortunately, my code just hangs.  After speaking with the fine people
>> > in #chicken, it seems that this may be a bug.  We played with different
>> > calls to put the threads to sleep, and different functions to read data,
>> > but they all ended up freezing at some point.
>> 
>> The ports obtained from calls to "open-[input|output]-file*" use
>> internally the "stream-port" class (ports on FILE* streams, in this
>> case created via fdopen(3)). These are not thread-aware, AFAICT. Ports
>> created for socket-fd's (tcp.scm) and processes (posixunix.scm, see
>> specifically ##sys#custom-[input|output]-port") apparently do.
>
> Is there a different way I should be opening the pipe so that it is
> thread aware?

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Aaron Patterson
On Wed, Oct 24, 2012 at 08:04:37AM -0400, Felix wrote:
> From: Aaron Patterson 
> Subject: [Chicken-users] Pipe and thread problem
> Date: Tue, 23 Oct 2012 14:30:57 -0700
> 
> > Hi, I'm trying to simulate reading from a TTY that writes every two
> > seconds.  I want to do this with a pipe and two threads, one thread
> > writes every N seconds, while the other reads any data available on the
> > pipe.
> > 
> > Unfortunately, my code just hangs.  After speaking with the fine people
> > in #chicken, it seems that this may be a bug.  We played with different
> > calls to put the threads to sleep, and different functions to read data,
> > but they all ended up freezing at some point.
> 
> The ports obtained from calls to "open-[input|output]-file*" use
> internally the "stream-port" class (ports on FILE* streams, in this
> case created via fdopen(3)). These are not thread-aware, AFAICT. Ports
> created for socket-fd's (tcp.scm) and processes (posixunix.scm, see
> specifically ##sys#custom-[input|output]-port") apparently do.

Is there a different way I should be opening the pipe so that it is
thread aware?

-- 
Aaron Patterson
http://tenderlovemaking.com/

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Jörg F . Wittenberger

Without having seen the code in question:
my guess would be that those FILE*-ports would
do i/o-buffering. flush-output might already help.
???

On Oct 24 2012, Felix wrote:


From: Mario Domenech Goulart 
Subject: Re: [Chicken-users] Pipe and thread problem
Date: Wed, 24 Oct 2012 09:44:37 -0400


Hi Felix,

On Wed, 24 Oct 2012 08:04:37 -0400 (EDT) Felix 
 wrote:



From: Aaron Patterson 
Subject: [Chicken-users] Pipe and thread problem
Date: Tue, 23 Oct 2012 14:30:57 -0700


Hi, I'm trying to simulate reading from a TTY that writes every two
seconds.  I want to do this with a pipe and two threads, one thread
writes every N seconds, while the other reads any data available on the
pipe.

Unfortunately, my code just hangs. After speaking with the fine 
people in #chicken, it seems that this may be a bug. We played with 
different calls to put the threads to sleep, and different functions 
to read data, but they all ended up freezing at some point.


The ports obtained from calls to "open-[input|output]-file*" use
internally the "stream-port" class (ports on FILE* streams, in this
case created via fdopen(3)). These are not thread-aware, AFAICT. Ports
created for socket-fd's (tcp.scm) and processes (posixunix.scm, see
specifically ##sys#custom-[input|output]-port") apparently do.


From a user perspective (i.e., without knowing how things are
implemented by Chicken), how can we know what procedures can be used
with threads?


Only from the documentation. I'm not sure I understand the question.
It also depends on how likely blocking is.



Wouldn't such a misuse of I/O operations in the presence of threads be
a possible cause of #858?


#858 refers to socket ports, which are implemented differently from
the ports that refer to files. Note that spiffy also involves sendfile,
which _does_ non-blocking I/O for files. I think.


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-us


___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Felix
From: Mario Domenech Goulart 
Subject: Re: [Chicken-users] Pipe and thread problem
Date: Wed, 24 Oct 2012 09:44:37 -0400

> Hi Felix,
> 
> On Wed, 24 Oct 2012 08:04:37 -0400 (EDT) Felix 
>  wrote:
> 
>> From: Aaron Patterson 
>> Subject: [Chicken-users] Pipe and thread problem
>> Date: Tue, 23 Oct 2012 14:30:57 -0700
>>
>>> Hi, I'm trying to simulate reading from a TTY that writes every two
>>> seconds.  I want to do this with a pipe and two threads, one thread
>>> writes every N seconds, while the other reads any data available on the
>>> pipe.
>>> 
>>> Unfortunately, my code just hangs.  After speaking with the fine people
>>> in #chicken, it seems that this may be a bug.  We played with different
>>> calls to put the threads to sleep, and different functions to read data,
>>> but they all ended up freezing at some point.
>>
>> The ports obtained from calls to "open-[input|output]-file*" use
>> internally the "stream-port" class (ports on FILE* streams, in this
>> case created via fdopen(3)). These are not thread-aware, AFAICT. Ports
>> created for socket-fd's (tcp.scm) and processes (posixunix.scm, see
>> specifically ##sys#custom-[input|output]-port") apparently do.
> 
> From a user perspective (i.e., without knowing how things are
> implemented by Chicken), how can we know what procedures can be used
> with threads?

Only from the documentation. I'm not sure I understand the question.
It also depends on how likely blocking is.

> 
> Wouldn't such a misuse of I/O operations in the presence of threads be
> a possible cause of #858?

#858 refers to socket ports, which are implemented differently from
the ports that refer to files. Note that spiffy also involves sendfile,
which _does_ non-blocking I/O for files. I think.


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Mario Domenech Goulart
Hi Felix,

On Wed, 24 Oct 2012 08:04:37 -0400 (EDT) Felix 
 wrote:

> From: Aaron Patterson 
> Subject: [Chicken-users] Pipe and thread problem
> Date: Tue, 23 Oct 2012 14:30:57 -0700
>
>> Hi, I'm trying to simulate reading from a TTY that writes every two
>> seconds.  I want to do this with a pipe and two threads, one thread
>> writes every N seconds, while the other reads any data available on the
>> pipe.
>> 
>> Unfortunately, my code just hangs.  After speaking with the fine people
>> in #chicken, it seems that this may be a bug.  We played with different
>> calls to put the threads to sleep, and different functions to read data,
>> but they all ended up freezing at some point.
>
> The ports obtained from calls to "open-[input|output]-file*" use
> internally the "stream-port" class (ports on FILE* streams, in this
> case created via fdopen(3)). These are not thread-aware, AFAICT. Ports
> created for socket-fd's (tcp.scm) and processes (posixunix.scm, see
> specifically ##sys#custom-[input|output]-port") apparently do.

>From a user perspective (i.e., without knowing how things are
implemented by Chicken), how can we know what procedures can be used
with threads?

Wouldn't such a misuse of I/O operations in the presence of threads be
a possible cause of #858?


Best wishes.
Mario
-- 
http://parenteses.org/mario

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Felix
From: Aaron Patterson 
Subject: [Chicken-users] Pipe and thread problem
Date: Tue, 23 Oct 2012 14:30:57 -0700

> Hi, I'm trying to simulate reading from a TTY that writes every two
> seconds.  I want to do this with a pipe and two threads, one thread
> writes every N seconds, while the other reads any data available on the
> pipe.
> 
> Unfortunately, my code just hangs.  After speaking with the fine people
> in #chicken, it seems that this may be a bug.  We played with different
> calls to put the threads to sleep, and different functions to read data,
> but they all ended up freezing at some point.

The ports obtained from calls to "open-[input|output]-file*" use
internally the "stream-port" class (ports on FILE* streams, in this
case created via fdopen(3)). These are not thread-aware, AFAICT. Ports
created for socket-fd's (tcp.scm) and processes (posixunix.scm, see
specifically ##sys#custom-[input|output]-port") apparently do.


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Alan Post
On Wed, Oct 24, 2012 at 09:32:35AM +0200, Peter Bex wrote:
> On Wed, Oct 24, 2012 at 03:21:15AM -0400, Felix wrote:
> > > Anyone with a better understanding of Chicken's internals able to
> > > comment on which cases poll() is called and how the timeout value is
> > > selected?
> > 
> > poll(2) is not used in the runtime system.
> 
> I think some libcs might implement select() in terms of poll?
> In that case, poll is what you'd see in a syscall trace.
> 

That's correct, libpthread on (at least my) version of OpenBSD
implements select in terms of poll.

-Alan
-- 
.i ma'a lo bradi cu penmi gi'e du

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Peter Bex
On Wed, Oct 24, 2012 at 03:21:15AM -0400, Felix wrote:
> > Anyone with a better understanding of Chicken's internals able to
> > comment on which cases poll() is called and how the timeout value is
> > selected?
> 
> poll(2) is not used in the runtime system.

I think some libcs might implement select() in terms of poll?
In that case, poll is what you'd see in a syscall trace.

Cheers,
Peter
-- 
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
-- Donald Knuth

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-24 Thread Felix
From: Alan Post 
Subject: Re: [Chicken-users] Pipe and thread problem
Date: Tue, 23 Oct 2012 16:14:17 -0600

> Anyone with a better understanding of Chicken's internals able to
> comment on which cases poll() is called and how the timeout value is
> selected?

poll(2) is not used in the runtime system.


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Pipe and thread problem

2012-10-23 Thread Alan Post
For me, that program is blocking on a call to poll(), which must be
something that is happening in chicken's threading code.

It is polling on two file descriptors with an infinite timeout, and
clearly never coming back up for air.

the produce thread is hanging on the thread-sleep call, and the consume
thread is hanging on the read-line call.  This means (and I confirm
in the ktrace) that your pipe is being written to.  If I add a
(newline writer) between your write and your flush, read-line
finishes once (I'd expect that) and then blocks again on read-line,
but the writing thread never wakes up.

I'm not sure why a (thread-sleep! 1) would ever cause poll to be
called with an infinite timeout, but a quick analysis shows that
some case is not waking up produce and you get to a point where both
ends of the pipe are waiting for the other one.

Anyone with a better understanding of Chicken's internals able to
comment on which cases poll() is called and how the timeout value is
selected?

-Alan

On Tue, Oct 23, 2012 at 02:30:57PM -0700, Aaron Patterson wrote:
> Hi, I'm trying to simulate reading from a TTY that writes every two
> seconds.  I want to do this with a pipe and two threads, one thread
> writes every N seconds, while the other reads any data available on the
> pipe.
> 
> Unfortunately, my code just hangs.  After speaking with the fine people
> in #chicken, it seems that this may be a bug.  We played with different
> calls to put the threads to sleep, and different functions to read data,
> but they all ended up freezing at some point.
> 
> Here is the program:
> 
> (use srfi-18)
> (use posix)
> 
> (define (produce writer)
>   (thread-start!
>(lambda ()
>  (print "producer started")
>  (let loop ((i 0))
>(display (conc "hello" i " ") writer)
>(flush-output writer)
>(thread-sleep! 1)
>(loop (+ i 1))
> 
> (define (consume reader)
>   (thread-start!
>(lambda ()
>  (print "consumer started")
>  (let loop ()
>(print (read-line reader))
>(loop)
> 
> (define (stream-test in-fd out-fd)
>   (let ((reader (open-input-file* in-fd))
> (writer (open-output-file* out-fd)))
> (produce writer)
> (thread-join! (consume reader
> 
> (call-with-values create-pipe stream-test)
> 
> Any help would be greatly appreciated.  Thanks!
> 
> -- 
> Aaron Patterson
> http://tenderlovemaking.com/
> 
> ___
> Chicken-users mailing list
> Chicken-users@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/chicken-users

-- 
.i ma'a lo bradi cu penmi gi'e du

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


[Chicken-users] Pipe and thread problem

2012-10-23 Thread Aaron Patterson
Hi, I'm trying to simulate reading from a TTY that writes every two
seconds.  I want to do this with a pipe and two threads, one thread
writes every N seconds, while the other reads any data available on the
pipe.

Unfortunately, my code just hangs.  After speaking with the fine people
in #chicken, it seems that this may be a bug.  We played with different
calls to put the threads to sleep, and different functions to read data,
but they all ended up freezing at some point.

Here is the program:

(use srfi-18)
(use posix)

(define (produce writer)
  (thread-start!
   (lambda ()
 (print "producer started")
 (let loop ((i 0))
   (display (conc "hello" i " ") writer)
   (flush-output writer)
   (thread-sleep! 1)
   (loop (+ i 1))

(define (consume reader)
  (thread-start!
   (lambda ()
 (print "consumer started")
 (let loop ()
   (print (read-line reader))
   (loop)

(define (stream-test in-fd out-fd)
  (let ((reader (open-input-file* in-fd))
(writer (open-output-file* out-fd)))
(produce writer)
(thread-join! (consume reader

(call-with-values create-pipe stream-test)

Any help would be greatly appreciated.  Thanks!

-- 
Aaron Patterson
http://tenderlovemaking.com/

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users