3

I am trying to create SV with newSVpvn() in the new thread created with pthread_create(). At this point my program crashes. C function where crash occures looks like this

void *_inet_aton(void *v_arg) {
    SV* rv = &PL_sv_undef;
    struct thread_arg *arg = (struct thread_arg *)v_arg;

    struct hostent *rslv = gethostbyname(arg->host);
    if (!rslv) {
        goto RET;
    }

    if (rslv->h_addrtype == AF_INET && rslv->h_length == 4) {
        // !!!CRASH HERE!!!
        rv = newSVpvn((char *)rslv->h_addr, rslv->h_length);
    }

    RET:
        free(arg->host);
        free(arg);
}

And XSUB

void
inet_aton(Net_DNS_Native *self, char *host)
    CODE:
        pthread_t tid;
        struct thread_arg *t_arg = malloc(sizeof(struct thread_arg));
        t_arg->self = self;
        t_arg->host = strdup(host);
        pthread_create(&tid, &self->thread_attrs, _inet_aton, (void *)t_arg);

Test example

use blib;
use Net::DNS::Native;


my $dns = Net::DNS::Native->new();
$dns->inet_aton("google.com");

# wait for a thread
sleep 10;

Full code may be found here: https://github.com/olegwtf/p5-Net-DNS-Native/blob/fbc57dbe9e6832afed8d46cd369db6930bbd53bc/Native.xs

So, is it possible to do what i want?

Oleg G
  • 925
  • 4
  • 12

1 Answers1

2

The fact it's crashing is a pretty good sign that you can't :)

Create the SV in a thread that actually has a Perl interpreter, i.e. when you fetch the resolved name.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    The idea was to use fd_set hash as storage for resolved names. Where key is file descriptor id returned to user on which he can poll() and value is resolved host name. So when fd will be ready for read user will get() result by file descriptor id. And in the thread result should be stored in this fd_set hash. But since we can't manipulate perl structures in the other thread I need to choose and use some pure C hash implementation to map fd to result. – Oleg G Sep 18 '14 at 16:54