FAQ
I have noticed that some things, for example a listening UDPConn, will exit
a pending Read() if they are Close()d. The error in this case is "read
udp: use of closed network connection"

Some other things will not, for example a Pipe() file.

For those cases where the Read() does not exit, what is a good pattern for
ensuring the Read() ends?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Dave Cheney at Mar 26, 2015 at 9:48 pm
    POSIX doesn't provide a way to unblock a blocking read from another thread. You have to close the other end of the pipe to unblock the reader. If that other end of the pipe belongs to another process, that process will have to die or close the file descriptor to unblock your reader.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Mar 26, 2015 at 10:15 pm

    On Thursday, March 26, 2015 at 5:48:32 PM UTC-4, Dave Cheney wrote:
    POSIX doesn't provide a way to unblock a blocking read from another
    thread. You have to close the other end of the pipe to unblock the reader.
    If that other end of the pipe belongs to another process, that process will
    have to die or close the file descriptor to unblock your reader.

    UDP does present a slightly unique problem though, there is no "pipe".
    In that case I've just filtered for that error message. Maybe the "use of
    closed network connection" error should have its value? (I admin I haven't
    read through this yet: https://github.com/golang/go/issues/4373)

    In the TCP case, you can use CloseRead to unblock a Read. Yet other cases,
    like a FIFO, you can't unblock without closing the write side of the pipe.
    There's no way to hide all the warts of our POSIX heritage.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Martin Garton at Mar 27, 2015 at 3:05 pm
    The actual case i care about is an open file /dev/net/tun. There is no other end to close. In c i would use a trick with a pipe I have both ends of and select over one end and the tun file. Clean close is then doable by closing or writing to the other end of the pipe. I cant find an equivalent in go yet.
    --

    ------------------------------
    This email was sent by a company owned by Pearson plc, registered office at
    80 Strand, London WC2R 0RL. Registered in England and Wales with company
    number 53723.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Mar 27, 2015 at 5:29 pm

    On Thu, Mar 26, 2015 at 7:05 PM, wrote:

    The actual case i care about is an open file /dev/net/tun. There is no
    other end to close. In c i would use a trick with a pipe I have both ends
    of and select over one end and the tun file. Clean close is then doable by
    closing or writing to the other end of the pipe. I cant find an equivalent
    in go yet.


    Ah yes, I've encountered that problem, and I punted by not canceling the
    Read at all, just letting it hang out there consuming a thread until the
    program exits. There is syscall.Select, but I'm not sure of a better way
    right now.

    I'd really love to be able to cancel reads on non-network files descriptors
    too.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nick Patavalis at Apr 24, 2015 at 8:41 am

    On Friday, March 27, 2015 at 7:29:41 PM UTC+2, James Bardin wrote:

    I'd really love to be able to cancel reads on non-network files
    descriptors too.
    On Linux you may find the following package useful, as it does exactly what
    you want (I think). I would be possible to modify it to work with other
    unixes (that don't have epoll(7)) and possibly with other OSes too (where
    applicable). I think it is the "correct" solution to the issues discussed
    in this thread...

       https://github.com/npat-efault/poller

    /npat


    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Martin Garton at Apr 24, 2015 at 11:07 am
    Thanks Nick.

    This looks appropriate to my needs and I'll take a deeper look.

    Meanwhile, I've updated https://gitlab.com/mjgarton/cancelio/tree/master to
    be simpler and essentially wrap *io.File with behaviour that aborts pending
    Read()s on Close().

    This also meets my needs and would be easier (for me at least) to make
    portable to other O/Ss, which will become a requirement for me in future.

    I can't help thinking that solutions to some of these kinds of things
    belong in the standard library, but I don't have a full enough
    understanding to suggest what that might look like.

    --
    Martin.

    On Friday, 24 April 2015 09:41:14 UTC+1, Nick Patavalis wrote:

    On Friday, March 27, 2015 at 7:29:41 PM UTC+2, James Bardin wrote:


    I'd really love to be able to cancel reads on non-network files
    descriptors too.
    On Linux you may find the following package useful, as it does exactly
    what you want (I think). I would be possible to modify it to work with
    other unixes (that don't have epoll(7)) and possibly with other OSes too
    (where applicable). I think it is the "correct" solution to the issues
    discussed in this thread...

    https://github.com/npat-efault/poller

    /npat
    --

    ------------------------------
    This email was sent by a company owned by Pearson plc, registered office at
    80 Strand, London WC2R 0RL. Registered in England and Wales with company
    number 53723.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • MartinG at Apr 27, 2015 at 12:41 pm
    I decided to add some benchmarks to my code at
    https://gitlab.com/mjgarton/cancelio/tree/master to give an indication of
    the overhead of the additional select() on throughput.

    To my surprise, I found things went significantly faster when going via my
    select code, than using the underlying Read() function directly.

    Can anyone explain that?

    --
    Martin.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Apr 27, 2015 at 12:47 pm
    At a wild guess, your code no longer blocks waiting for a fd to be ready,
    this will reduce the number of threads blocked on a syscall, which reduces
    pressure on the scheduler. If you only Read from an fd when it is ready the
    scheduler will be able to avoid the overhead of creating a replacement
    thread as the one that just jumped to Read will return effectively
    immediately.
    On Monday, 27 April 2015 22:41:01 UTC+10, MartinG wrote:

    I decided to add some benchmarks to my code at
    https://gitlab.com/mjgarton/cancelio/tree/master to give an indication
    of the overhead of the additional select() on throughput.

    To my surprise, I found things went significantly faster when going via my
    select code, than using the underlying Read() function directly.

    Can anyone explain that?

    --
    Martin.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • MartinG at Apr 16, 2015 at 9:22 pm
    I got annoyed at this problem and tried to find a solution. I have
    something that works but required some c.

    You can find my attempt here:
    https://gitlab.com/mjgarton/cancelio/tree/master

    It doesn't abort the Read() but from the callers perspective it has the
    equivalent effect.

    I'd really like this to be possible in pure go somehow.

    --
    Martin.
    On Thursday, March 26, 2015 at 9:48:32 PM UTC, Dave Cheney wrote:

    POSIX doesn't provide a way to unblock a blocking read from another
    thread. You have to close the other end of the pipe to unblock the reader.
    If that other end of the pipe belongs to another process, that process will
    have to die or close the file descriptor to unblock your reader.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Apr 16, 2015 at 9:43 pm

    On Thu, Apr 16, 2015 at 5:22 PM, MartinG wrote:

    I got annoyed at this problem and tried to find a solution. I have
    something that works but required some c.

    You can find my attempt here:
    https://gitlab.com/mjgarton/cancelio/tree/master

    It doesn't abort the Read() but from the callers perspective it has the
    equivalent effect.

    I'd really like this to be possible in pure go somehow.
    You're leaking the dup'ed file descriptor (and maybe a thread with each?, I
    didn't look too closely).
    If you want to get rid of cgo, did using the syscall.Select directly?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • MartinG at Apr 22, 2015 at 5:36 pm

    You're leaking the dup'ed file descriptor (and maybe a thread with each?,
    I didn't look too closely).
    If you want to get rid of cgo, did using the syscall.Select directly?
    Thanks.

    I've updated the code at https://gitlab.com/mjgarton/cancelio/tree/master

    It is now in pure go and uses syscall directly as you suggested.

    Any thoughts on how I might avoid leaking dup'ed file descriptor? I have
    to admit I don't fully understand dup() or why it us being used.

    --
    Martin.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Apr 22, 2015 at 6:40 pm

    On Wed, Apr 22, 2015 at 1:36 PM, MartinG wrote:

    It is now in pure go and uses syscall directly as you suggested.

    Any thoughts on how I might avoid leaking dup'ed file descriptor? I have
    to admit I don't fully understand dup() or why it us being used.
    The original file descriptor for a socket can't be exposed outside of the
    net package, so when you call conn.File(), it returns a dup of that
    underlying file descriptor with both of them now in blocking mode. You will
    need to eventually call Close on both of those files, but you're currently
    losing track of that new *os.File and its fd.

    You should also have way to close the read side of the pipe when you're
    done too.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Aram Hăvărneanu at Apr 16, 2015 at 10:09 pm

    On Thu, Mar 26, 2015 at 10:48 PM, Dave Cheney wrote:
    POSIX doesn't provide a way to unblock a blocking read from another thread.
    You can send a signal to interrupt a system call.

    --
    Aram Hăvărneanu

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Matt Harden at Apr 23, 2015 at 1:13 am

    On Thu, Apr 16, 2015 at 5:10 PM Aram Hăvărneanu wrote:
    On Thu, Mar 26, 2015 at 10:48 PM, Dave Cheney wrote:
    POSIX doesn't provide a way to unblock a blocking read from another
    thread.

    You can send a signal to interrupt a system call.
    I'm curious - any idea how to send a signal to the appropriate thread
    blocked on Read? How do we determine the thread ID?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Apr 23, 2015 at 1:54 am
    Don't do that, use a poller and the self pipe trick.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Apr 23, 2015 at 3:40 am

    On Wed, Apr 22, 2015 at 6:12 PM, Matt Harden wrote:
    On Thu, Apr 16, 2015 at 5:10 PM Aram Hăvărneanu wrote:
    On Thu, Mar 26, 2015 at 10:48 PM, Dave Cheney wrote:
    POSIX doesn't provide a way to unblock a blocking read from another
    thread.
    You can send a signal to interrupt a system call.

    I'm curious - any idea how to send a signal to the appropriate thread
    blocked on Read? How do we determine the thread ID?
    It won't work in Go anyhow, because the Go runtime sets the SA_RESTART
    flag on all the signal handlers.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Aram Hăvărneanu at Apr 23, 2015 at 10:48 am

    On Thu, Apr 23, 2015 at 5:39 AM, Ian Lance Taylor wrote:
    It won't work in Go anyhow, because the Go runtime sets the SA_RESTART
    flag on all the signal handlers.
    It's true that it won't work in Go in Unix, I was answering the
    problem more abstractly.

    It works, however, in Plan 9; this is how deadlines and cancelations
    are implemented in the net package.

    --
    Aram Hăvărneanu

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 26, '15 at 9:27p
activeApr 27, '15 at 12:47p
posts18
users8
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase