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
|
/*
* Copyright (C) 2014 Zheng Li <dev@zheng.li>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/
#include <poll.h>
#include <errno.h>
#include <sys/resource.h>
#include <unistd.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/fail.h>
#include <caml/alloc.h>
#include <caml/signals.h>
#include <caml/unixsupport.h>
CAMLprim value stub_select_on_poll(value fd_events, value timeo) {
CAMLparam2(fd_events, timeo);
CAMLlocal1(events);
int i, rc, c_len = Wosize_val(fd_events), c_timeo = Int_val(timeo);
struct pollfd c_fds[c_len];
for (i = 0; i < c_len; i++) {
events = Field(Field(fd_events, i), 1);
c_fds[i].fd = Int_val(Field(Field(fd_events, i), 0));
c_fds[i].events = c_fds[i].revents = 0;
c_fds[i].events |= Bool_val(Field(events, 0)) ? POLLIN : 0;
c_fds[i].events |= Bool_val(Field(events, 1)) ? POLLOUT: 0;
c_fds[i].events |= Bool_val(Field(events, 2)) ? POLLPRI: 0;
};
caml_enter_blocking_section();
rc = poll(c_fds, c_len, c_timeo);
caml_leave_blocking_section();
if (rc < 0) uerror("poll", Nothing);
if (rc > 0) {
for (i = 0; i < c_len; i++) {
events = Field(Field(fd_events, i), 1);
if (c_fds[i].revents & POLLNVAL) unix_error(EBADF, "select", Nothing);
Field(events, 0) = Val_bool(c_fds[i].events & POLLIN && c_fds[i].revents & (POLLIN |POLLHUP|POLLERR));
Field(events, 1) = Val_bool(c_fds[i].events & POLLOUT && c_fds[i].revents & (POLLOUT|POLLHUP|POLLERR));
Field(events, 2) = Val_bool(c_fds[i].revents & POLLPRI);
}
}
CAMLreturn(Val_int(rc));
}
CAMLprim value stub_set_fd_limit(value limit) {
CAMLparam1(limit);
struct rlimit rl;
rl.rlim_cur = rl.rlim_max = Int_val(limit);
if (setrlimit(RLIMIT_NOFILE, &rl) != 0) uerror("setrlimit", Nothing);
CAMLreturn(Val_unit);
}
|