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