I am attempting to use EV/libev from Inline::C in an attempt to use
direct callbacks to C functions for a few performance critical
portions of a project I am working on.

However, I am fairly new to C in general and have run into a brick wall.
Whenever I attempt to start a watcher, I either create some kind of
infinite loop, or cause a segfault. I think it is related to
attempting access to the default loop but I am unsure.

I have attached an example of a simple UDP echo server that I am
attempting to get working as a learning device.

Would anyone mind taking a look at it and telling me where I am going
wrong? Or is what I am attempting just not possible?

Any input is welcome.

Thanks,

Ryan
#!/usr/bin/env perl
use strict;
use warnings;
use IO::Socket::INET;
use Socket;
use EV;

my $sock = IO::Socket::INET->new(LocalAddr => '127.0.0.1', LocalPort => 8000, Proto => 'udp', Blocking => 0) or die "$!";

my $file = fileno($sock);

die "Negative file descriptor" if ($file < 0);

my $echo = Echoer->new($file) or die "Could not make echoer";

print "FD is ", $echo->fd(), "\n";

EV::run;

package Echoer;
use Inline C => 'DATA';
use Inline C => Config => INC => "-I/paththatcontainsEV/", BUILD_NOISY => 1,
MYEXTLIB => '/path/auto/EV/EV.so';

1;
__DATA__
__C__
#include "EV/ev.h"

typedef struct {
	ev_io watcher;
	int fd;
} echoer;

void echo (EV_P_ ev_io *w, int revents) {
	echoer* self = (echoer*)w;

	char buf[65536];
	struct sockaddr_in from_addr;
	int recvd;
	int sent;
	printf("Called\n");
	while((recvd = recvfrom(self->fd, &buf, 65535, MSG_DONTWAIT, &from_addr, sizeof(from_addr))) > 0 ) {
		sent = sendto(self->fd, &buf, recvd, MSG_DONTWAIT, &from_addr, sizeof(from_addr));
		if (sent < 0) {
			return;
		}
	}

	return;

}

//Constructor
SV* new(char* class, int fd) {
	echoer* self;
	SV* obj_ref = newSViv(0);
	SV* obj = newSVrv(obj_ref, class);

	Newx(self, 1, echoer);

	self->fd = fd;

	ev_io_init(&self->watcher, echo, self->fd, EV_READ);
	printf("Starting watcher for events %d\n", EV_READ);
	ev_io_start(EV_DEFAULT, &self->watcher);

	sv_setiv(obj, (IV)self);

	SvREADONLY_on(obj);
	return obj_ref;
}

//accessor
int fd(SV* obj) {
	echoer* self = (echoer*)SvIV(SvRV(obj));
	return self->fd;
}

void DESTROY(SV* obj) {
	printf("Destructor called\n");
	echoer* self = (echoer*)SvIV(SvRV(obj));
	ev_io_stop(EV_DEFAULT, &self->watcher);
	Safefree(self);
}
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to