RFC: AnyEvent::Handle with two non-duplex filehandles
Marc Lehmann
schmorp at schmorp.de
Mon Apr 22 11:10:27 CEST 2013
On Mon, Apr 22, 2013 at 03:37:54PM +1200, Mark Lawrence <nomad at null.net> wrote:
> I wish I only had one handle for reading and writing to ssh, but how do
> you arrange that?
create a socketpair, fork, dup it over stdin and stdout, exec ssh and you
are done. no need for fancy modules either.
> The inter-process communication tools I've seen
> (open(),
I didn't know open returned or required two handles, how do you do that?
> IPC::* etc) all seem to return or require separate in/out
Are you sure they require separate handles? That happens when you pass in
the same handle for stdin and stdout?
I must admit I never used any of the IPC modules that come with perl
because they never seem to do anything useful that I couldn't do better
without them. Maybe it's time to deprecate those, but thats probably just
me :)
> handles. Is there a trick I'm not aware of for combining the child
> process Stdin and Stdout filehandles into one?
A file handle is a perl construct - what counts to ssh is the file
descriptor, and while those are diferent integers for stdin and stdout,
they will happily refer to the same underlying file description (e.g. a
socket or some other full-duplex pipe).
> > I think using weak references or explicit ->destroy calls should take
> > care of these loops without too much effort.
>
> I think the challenge I am facing is not knowning all of the places I
> should be using ->destroy. However weakening the references (which I
> haven't used here yet) may well sort things out.
You need to destroy when you no longer need the handle, which should
be reaosnably easy to identify (e.g. in on_error, or when you finsihed
talking to the server).
> I'm facing something of a call-back hell due to needing to maintain
> state between events, possibly resulting in lexical variables (i.e.
> filehandles) being passed into multiple anonymous subrefs where I
> assume they are not weak:
>
> $state = calculate_state();
> $whl->push_write(...);
>
> $rdl->push_read(line => sub {
> $state = calculate_state_again();
>
> # handle the read, and then push another write...
> $whl->push_write(...);
> $rdl->push_read(...);
> });
If $whl is weak to begin with, it will stay weak inside the close passed
to push_readline as well.
The easy solution that should alwas work is have a wrapper object that
only points to the real object(s) - since nothing inside keeps a reference
to the wrapper, it's DESTROY can unravel the object hierarchy. XML::Parser
uses this for example.
--
The choice of a Deliantra, the free code+content MORPG
-----==- _GNU_ http://www.deliantra.net
----==-- _ generation
---==---(_)__ __ ____ __ Marc Lehmann
--==---/ / _ \/ // /\ \/ / schmorp at schmorp.de
-=====/_/_//_/\_,_/ /_/\_\
More information about the anyevent
mailing list