Re: XS to return Perl Arrays - and NetWare Select()

[email protected] (Josh Goldberg)
Newsgroups perl.xs
Message-ID <[email protected]>
What I do is something like

AV *results;
results = newAV();
....
something = (AV *)SvRV(*other_av_thing);
....
av_store(results,i, something);
....
RETVAL = results;
sv_2mortal((SV *)RETVAL);

On Wed, Jun 8, 2011 at 4:11 PM, NormW <[email protected]> wrote:
> Hi All,
> AFAICT, I want to implement the following Perl call to XS code:
>
> my (@ro,@wo,@eo) = nw_select(\@ri,\@wi,\@ei,$wait);
>
> What I think I need is XS code to return the 3 LHS arrays or 'undef's as
> appropriate. PerlXSTut Sample 7 seems a possible ideas source but alas it is
> in the 'Coming soon' category at last check.
>
> BACKGROUND
>
> NetWare's fd_set struct is an FD_SETSIZE array of int's + a counter to
> identify the last entry in the array, each int able to store a socket
> handle. (NetWare select() does not work with file descriptors). This means,
> AFAICT, it would be messy to patch the Perl pp_sselect code for NetWare, so
> decided a separate XS module would better serve the task.
>
> Based on Perl XS docs and the XS code in the Perl source, I have put the
> following XS code together, although for simplicity and compactness here
> will only include the 'can_read' array... Any feedback regarding the
> correctness of the code so far is much appreciated, as the NetWare debugger
> is just as 'unique' and I would like the best chance to only have problems
> in the Perl code when I try getting this to work!
>
> Lastly, based on Perl conventions, would the resulting module be more
> appropriately named as IO::Select::NetWare or NetWare::Select, as I have
> seen some Linux:: modules extant??
>
> Now, finally, the XS code adapted/borrowed so far.
>
>> int
>> nw_select(reads, writes, errors, wtime)
>>  SV* reads
>>  SV* writes
>>  SV* errors
>>  SV* wtime
>> PREINIT:
>>  NV value;
>>  struct timeval timebuf;
>>  struct timeval *tbuf = &timebuf;
>>  SV *fd = NULL;
>>  int numfds = 0;
>>  int nfound = 0;
>>  int i;
>>  fd_set rdfds, wrfds, erfds;
>>  fd_set *prds = NULL, *pwrs = NULL, *pers = NULL;
>> CODE:
>>  /* Wait Time */
>>  if (SvOK(wtime)) {
>>    value = SvNV(wtime);
>>    if (value < 0.0)
>>      value = 0.0;
>>    timebuf.tv_sec  = (long)value;
>>    value          -= (NV)timebuf.tv_sec;
>>    timebuf.tv_usec = (long)(value * 1000000.0);
>>  }
>>  else
>>    tbuf = NULL;
>>  /* Reads */
>>  if ((SvROK(reads)) && (SvTYPE(SvRV(reads)) == SVt_PVAV)) {
>>    prds = &rdfds;
>>    FD_ZERO(prds);
>>    while (av_len((AV*)reads) >= 0) {
>>      if (rdfds.fd_count >= FD_SETSIZE)
>>        croak("Too many sockets passed to NeWare::select(rd): Max ",
>> FD_SETSIZE);
>>      fd = (SV*)av_shift((AV*)reads);
>>      FD_SET(SvIV(fd), prds);
>>    }
>>    numfds += rdfds.fd_count;
>>  }
>
> [....]
>>
>>  /* Call LibC */
>>  nfound = select( numfds + 1, prds, pwrs, pers, tbuf );
>>  /* Reads */
>>  if (prds == NULL) {
>>    ST(0) = &PL_sv_undef;
>>  } else {
>>    ST(0) = newAV();
>>    sv_2mortal((SV*)ST(0));
>>    for (i = 0 ; i < rdfds.fd_count ; i++) {
>>      sv_setpviv(fd, rdfds.fd_array[i]);
>>      av_push(ST(0), fd);
>>    }
>>  }
>
> Any and all feedback/comments welcome.
> TIA,
> Norm
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.