Calling writev and readv from perl

A

A. Farber

Hello,

is there a way to call writev(2) from Perl?

I'm porting a C-program to Perl and
have a spot there, where a linked list
of data is being writev()ed to a socket.

In the Perl-script that would be an array,
which I'd need to writev() to the socket.

There are very few hits, when I search
for "perl" and "writev" in Google...

Thank you
Alex
 
B

Ben Morrow

Quoth "A. Farber said:
Hello,

is there a way to call writev(2) from Perl?

Not AFAIK. While it would be perfectly possible to write an extension
that provided it, you would need to be really sure it was worth it. IO
in Perl is usually buffered, and joining several strings together before
writing them with print or syswrite is a more usual way of emulating
writev(2). Perl has a habit of trading memory for speed and simplicity;
if this is inappropriate for your application, consider whether Perl is
the right choice of language.

Ben
 
L

Leon Timmermans

Hello,

is there a way to call writev(2) from Perl?

I'm porting a C-program to Perl and
have a spot there, where a linked list of data is being writev()ed to a
socket.

In the Perl-script that would be an array, which I'd need to writev() to
the socket.

There are very few hits, when I search for "perl" and "writev" in
Google...

Thank you
Alex

Porting a C program to perl that verbatim is probably a bad idea. The
easiest solution would be to just write the elements individually.

If you really want to do it the writev way, it is definitely possible. I
think this code should do it, but I haven't really tested it yet.

use Symbol qw/qualify_to_ref/;
BEGIN { require 'syscall.ph' };

sub writev(*@) {
my $fh = qualify_to_ref(shift, caller);
my $vector = join '', map { pack 'PI', $_, length } @_;
return syscall SYS_writev, fileno $fh, $vector, scalar @_;
}

sub readv(*@) {
my $fh = qualify_to_ref(shift, caller);
my $vector = join '', map { pack 'PI', $_, length } @_;
return syscall SYS_readv, fileno $fh, $vector, scalar @_;
}

They both take a filehandle as first argument.

Regards,

Leon Timmermans
 
A

A. Farber

easiest solution would be to just write the elements individually.

Thank you, but that would degrade the performance
of my non-forking server too much, because:

currently in the C-program the whole linked list
is often being written out (to an Apache child via
Unix socket) in a single writev() call - after poll()
has reported that a write/writev call wouldn't block.

If I switch to syswriting every element individually,
then I'll also have to call IO::poll::poll inbetween...
use Symbol qw/qualify_to_ref/;
BEGIN { require 'syscall.ph' };

subwritev(*@) {
    my $fh = qualify_to_ref(shift, caller);
    my $vector = join '', map { pack 'PI', $_, length } @_;
    return syscall SYS_writev, fileno $fh, $vector, scalar @_;

}

sub readv(*@) {
    my $fh = qualify_to_ref(shift, caller);
    my $vector = join '', map { pack 'PI', $_, length } @_;
    return syscall SYS_readv, fileno $fh, $vector, scalar @_;

}

This and Inline::C look too complicated for me for now.
And I'm not sure how stable those interfaces are
(in various perl versions).

I'll try going with concatenating data to 1 big string
as Ben suggested

Regards
Alex
 
X

xhoster

A. Farber said:
Thank you, but that would degrade the performance
of my non-forking server too much, because:

You are rewriting C into Perl, yet are that concerned about
performance at this level?
currently in the C-program the whole linked list
is often being written out (to an Apache child via
Unix socket) in a single writev() call - after poll()
has reported that a write/writev call wouldn't block.

I don't see how this could work. Poll doesn't guarantee that an
arbitrarily large amount of data can be written without blocking,
just that at least one byte (or maybe one "block") can be.

Unless your poll and my poll are not the same thing.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
L

Leon Timmermans

Thank you, but that would degrade the performance of my non-forking
server too much, because:

Would it? How many elements are we talking about? Half a dozen? Hundreds?
after poll() has reported that a write/writev call wouldn't block.
If I switch to syswriting every element individually, then I'll also
have to call IO::poll::poll inbetween...

If you don't want it to block, you should use real non-blocking IO, not
this hack.
I'll try going with concatenating data to 1 big string
as Ben suggested

Probably the best idea.

Regards,

Leon Timmermans
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top