File: Epoll.xs

package info (click to toggle)
libio-epoll-perl 0.03-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 168 kB
  • sloc: perl: 404; pascal: 92; makefile: 2
file content (114 lines) | stat: -rw-r--r-- 2,348 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include <sys/epoll.h>

#include "const-c.inc"

MODULE = IO::Epoll		PACKAGE = IO::Epoll		

INCLUDE: const-xs.inc

int
epoll_create(size)
	int size

int
epoll_ctl(epfd,op,fd,events)
	int epfd
	int op
	int fd
	unsigned long events
CODE:
	struct epoll_event event;
	int ret;
	event.events = events;
	event.data.fd = fd;

	RETVAL = epoll_ctl(epfd, op, fd, &event);
OUTPUT:
	RETVAL

SV *
epoll_wait(epfd,maxevents,timeout)
	int epfd
	int maxevents
	int timeout
CODE:
	struct epoll_event *events;
	int ret, i;

	events = (struct epoll_event *)malloc(maxevents * sizeof(struct epoll_event));
	if (!events) {
		errno = ENOMEM;
		XSRETURN_UNDEF;
	}
	ret = epoll_wait(epfd, events, maxevents, timeout);
	if (ret < 0) {
		free(events);
		XSRETURN_UNDEF;
	} else {
		AV *results = (AV*)sv_2mortal((SV*)newAV());
		for (i = 0; i < ret; i++) {
			AV *ev = (AV*)sv_2mortal((SV*)newAV());
			av_push(ev, newSVnv(events[i].data.fd));
			av_push(ev, newSVnv(events[i].events));
			av_push(results, newRV((SV*) ev));
		}
		RETVAL = newRV((SV *)results);
		free(events);
	}
OUTPUT:
	RETVAL

SV *
epoll_pwait(epfd,maxevents,timeout,sigmask)
	int epfd
	int maxevents
	int timeout
	SV *sigmask
CODE:
	struct epoll_event *events;
	sigset_t *sigmask_real;
	int ret, i;

	if(SvOK(sigmask)) {
		if(!sv_derived_from(sigmask, "POSIX::SigSet"))
			Perl_croak(aTHX_ "epoll_pwait: sigmask is not of type POSIX::SigSet");
#if PERL_VERSION > 15 || PERL_VERSION == 15 && PERL_SUBVERSION > 2
        sigmask_real = (sigset_t *) SvPV_nolen(SvRV(sigmask));
#else
		/* This code borrowed from POSIX.xs */
		IV tmp = SvIV((SV*)SvRV(sigmask));
		sigmask_real = INT2PTR(sigset_t*, tmp);
#endif
	}
	else {
		sigmask_real = NULL;
	}

	events = (struct epoll_event *)malloc(maxevents * sizeof(struct epoll_event));
	if (!events) {
		errno = ENOMEM;
		XSRETURN_UNDEF;
	}
	ret = epoll_pwait(epfd, events, maxevents, timeout, sigmask_real);
	if (ret < 0) {
		free(events);
		XSRETURN_UNDEF;
	} else {
		AV *results = (AV*)sv_2mortal((SV*)newAV());
		for (i = 0; i < ret; i++) {
			AV *ev = (AV*)sv_2mortal((SV*)newAV());
			av_push(ev, newSVnv(events[i].data.fd));
			av_push(ev, newSVnv(events[i].events));
			av_push(results, newRV((SV*) ev));
		}
		RETVAL = newRV((SV *)results);
		free(events);
	}
OUTPUT:
	RETVAL