]> git.proxmox.com Git - ceph.git/blame - ceph/src/civetweb/src/third_party/duktape-1.3.0/examples/eventloop/c_eventloop.js
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.3.0 / examples / eventloop / c_eventloop.js
CommitLineData
7c673cae
FG
1/*
2 * C eventloop example (c_eventloop.c).
3 *
4 * Ecmascript code to initialize the exposed API (setTimeout() etc) when
5 * using the C eventloop.
6 *
7 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Timers
8 */
9
10/*
11 * Timer API
12 */
13
14function setTimeout(func, delay) {
15 var cb_func;
16 var bind_args;
17 var timer_id;
18
19 if (typeof delay !== 'number') {
20 throw new TypeError('delay is not a number');
21 }
22
23 if (typeof func === 'string') {
24 // Legacy case: callback is a string.
25 cb_func = eval.bind(this, func);
26 } else if (typeof func !== 'function') {
27 throw new TypeError('callback is not a function/string');
28 } else if (arguments.length > 2) {
29 // Special case: callback arguments are provided.
30 bind_args = Array.prototype.slice.call(arguments, 2); // [ arg1, arg2, ... ]
31 bind_args.unshift(this); // [ global(this), arg1, arg2, ... ]
32 cb_func = func.bind.apply(func, bind_args);
33 } else {
34 // Normal case: callback given as a function without arguments.
35 cb_func = func;
36 }
37
38 timer_id = EventLoop.createTimer(cb_func, delay, true /*oneshot*/);
39
40 return timer_id;
41}
42
43function clearTimeout(timer_id) {
44 if (typeof timer_id !== 'number') {
45 throw new TypeError('timer ID is not a number');
46 }
47 var success = EventLoop.deleteTimer(timer_id); /* retval ignored */
48}
49
50function setInterval(func, delay) {
51 var cb_func;
52 var bind_args;
53 var timer_id;
54
55 if (typeof delay !== 'number') {
56 throw new TypeError('delay is not a number');
57 }
58
59 if (typeof func === 'string') {
60 // Legacy case: callback is a string.
61 cb_func = eval.bind(this, func);
62 } else if (typeof func !== 'function') {
63 throw new TypeError('callback is not a function/string');
64 } else if (arguments.length > 2) {
65 // Special case: callback arguments are provided.
66 bind_args = Array.prototype.slice.call(arguments, 2); // [ arg1, arg2, ... ]
67 bind_args.unshift(this); // [ global(this), arg1, arg2, ... ]
68 cb_func = func.bind.apply(func, bind_args);
69 } else {
70 // Normal case: callback given as a function without arguments.
71 cb_func = func;
72 }
73
74 timer_id = EventLoop.createTimer(cb_func, delay, false /*oneshot*/);
75
76 return timer_id;
77}
78
79function clearInterval(timer_id) {
80 if (typeof timer_id !== 'number') {
81 throw new TypeError('timer ID is not a number');
82 }
83 EventLoop.deleteTimer(timer_id);
84}
85
86function requestEventLoopExit() {
87 EventLoop.requestExit();
88}
89
90/*
91 * Socket handling
92 *
93 * Ideally this would be implemented more in C than here for more speed
94 * and smaller footprint: C code would directly maintain the callback state
95 * and such.
96 *
97 * Also for more optimal I/O, the buffer churn caused by allocating and
98 * freeing a lot of buffer values could be eliminated by reusing buffers.
99 * Socket reads would then go into a pre-allocated buffer, for instance.
100 */
101
102EventLoop.socketListening = {};
103EventLoop.socketReading = {};
104EventLoop.socketConnecting = {};
105
106EventLoop.fdPollHandler = function(fd, revents) {
107 var data;
108 var cb;
109 var rc;
110 var acc_res;
111
112 //print('activity on fd', fd, 'revents', revents);
113
114 if (revents & Poll.POLLIN) {
115 cb = this.socketReading[fd];
116 if (cb) {
117 data = Socket.read(fd); // no size control now
118 //print('READ', Duktape.enc('jx', data));
119 if (data.length === 0) {
120 this.close(fd);
121 return;
122 }
123 cb(fd, data);
124 } else {
125 cb = this.socketListening[fd];
126 if (cb) {
127 acc_res = Socket.accept(fd);
128 //print('ACCEPT:', Duktape.enc('jx', acc_res));
129 cb(acc_res.fd, acc_res.addr, acc_res.port);
130 } else {
131 //print('UNKNOWN');
132 }
133 }
134 }
135
136 if (revents & Poll.POLLOUT) {
137 // Connected
138 cb = this.socketConnecting[fd];
139 if (cb) {
140 delete this.socketConnecting[fd];
141 cb(fd);
142 }
143 }
144
145 if ((revents & ~(Poll.POLLIN | Poll.POLLOUT)) !== 0) {
146 //print('unexpected revents, close fd');
147 this.close(fd);
148 }
149}
150
151EventLoop.server = function(address, port, cb_accepted) {
152 var fd = Socket.createServerSocket(address, port);
153 this.socketListening[fd] = cb_accepted;
154 this.listenFd(fd, Poll.POLLIN);
155}
156
157EventLoop.connect = function(address, port, cb_connected) {
158 var fd = Socket.connect(address, port);
159 this.socketConnecting[fd] = cb_connected;
160 this.listenFd(fd, Poll.POLLOUT);
161}
162
163EventLoop.close = function(fd) {
164 EventLoop.listenFd(fd, 0);
165 delete this.socketListening[fd];
166 delete this.socketReading[fd];
167 delete this.socketConnecting[fd];
168 Socket.close(fd);
169}
170
171EventLoop.setReader = function(fd, cb_read) {
172 this.socketReading[fd] = cb_read;
173 this.listenFd(fd, Poll.POLLIN);
174}
175
176EventLoop.write = function(fd, data) {
177 // This simple example doesn't have support for write blocking / draining
178 var rc = Socket.write(fd, Duktape.Buffer(data));
179}