Skip Menu |

This queue is for tickets about the X11-Protocol CPAN distribution.

Report information
The Basics
Id: 38972
Status: open
Priority: 0/
Queue: X11-Protocol

People
Owner: SMCCAM [...] cpan.org
Requestors: mweber [...] mit.jyu.fi
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.03
Fixed in: (no value)



Subject: X11::Protocol fails when connecting to multiple X servers
Date: Thu, 4 Sep 2008 09:09:13 +0300
To: bug-X11-Protocol [...] rt.cpan.org
From: Matthieu Weber <mweber [...] mit.jyu.fi>
Hi, This fails: use X11::Protocol; # "unix:0.0" is the local display, "localhost:10.0" is a remote display # accessed with an SSH tunnel for $display ("unix:0.0", "localhost:10.0") { $x = X11::Protocol->new($display); $x->init_extension('SHAPE'); $x->ShapeQueryVersion($x->root); } The reason is that in the AUTOLOAD method of X11::Protocol, there is *{$AUTOLOAD} = sub {blah blah} which makes the method a closure, in which the value of $major is fixed to the value of SHAPE's major opcode in the first X server. But when you connect to the second X server, this method is not deleted when the first X11::Protocol object is garbage collected, and it is reused with the second X server, but it fails as the major opcode value for SHAPE is then different. I'm not sure how to fix this, the workaround I currently use is to call undef *X11::Protocol::ShapeQueryVersion; before creating a new instance of X11::Protocol. FYI, I am using X11-Protocol-0.55 and perl v5.8.8 on Debian 4.0. Matthieu -- (~._.~) Matthieu Weber - Université de Jyväskylä (~._.~) ( ? ) email : mweber@mit.jyu.fi ( ? ) ()- -() public key id : 452AE0AD ()- -() (_)-(_) "Humor ist, wenn man trotzdem lacht (Otto J. Bierbaum)" (_)-(_)
On Thu Sep 04 02:09:54 2008, mweber@mit.jyu.fi wrote: Show quoted text
> Hi, > > This fails: > > use X11::Protocol; > # "unix:0.0" is the local display, "localhost:10.0" is a remote display > # accessed with an SSH tunnel > for $display ("unix:0.0", "localhost:10.0") { > $x = X11::Protocol->new($display); > $x->init_extension('SHAPE'); > $x->ShapeQueryVersion($x->root); > } > > The reason is that in the AUTOLOAD method of X11::Protocol, there is > > *{$AUTOLOAD} = sub {blah blah} > > which makes the method a closure, in which the value of $major is fixed > to the value of SHAPE's major opcode in the first X server. But when you > connect to the second X server, this method is not deleted when the > first X11::Protocol object is garbage collected, and it is reused with > the second X server, but it fails as the major opcode value for SHAPE is > then different. > > I'm not sure how to fix this, the workaround I currently use is to call > > undef *X11::Protocol::ShapeQueryVersion; > > before creating a new instance of X11::Protocol. > > FYI, I am using X11-Protocol-0.55 and perl v5.8.8 on Debian 4.0.
Yes, that analysis looks correct. The AUTOLOAD handler is doing some excessive optimization and hardcoding the opcode in the sub it builds. This wouldn't be a problem for core requests, but it's a problem for extension requests like this, because their opcodes vary from server to server. The fanciest solution would be to add a separate case for extension requests that builds a sub that looks up the opcodes each time. Slightly slower solutions would be to do that for all requests, or to remove the whole "Make this faster next time" block (I have no idea if it ever makes a noticeable difference). Another workaround would be to use ->req for extension requests.