Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: c/network.c

Issue 2842333002: Updated netty-tcnative to version 2.0.0.Final (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « c/native_constants.c ('k') | c/os.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 *
19 * @author Mladen Turk
20 * @version $Id: network.c 1607296 2014-07-02 08:45:42Z kkolinko $
21 */
22
23 #include "tcn.h"
24
25 #ifdef TCN_DO_STATISTICS
26
27 #include "apr_atomic.h"
28
29 static volatile apr_uint32_t sp_created = 0;
30 static volatile apr_uint32_t sp_closed = 0;
31 static volatile apr_uint32_t sp_cleared = 0;
32 static volatile apr_uint32_t sp_accepted = 0;
33 static volatile apr_uint32_t sp_max_send = 0;
34 static volatile apr_uint32_t sp_min_send = 10000000;
35 static volatile apr_uint32_t sp_num_send = 0;
36 static volatile apr_off_t sp_tot_send = 0;
37 static volatile apr_uint32_t sp_max_recv = 0;
38 static volatile apr_uint32_t sp_min_recv = 10000000;
39 static volatile apr_uint32_t sp_num_recv = 0;
40 static volatile apr_off_t sp_tot_recv = 0;
41 static volatile apr_uint32_t sp_err_recv = 0;
42 static volatile apr_uint32_t sp_tmo_recv = 0;
43 static volatile apr_uint32_t sp_rst_recv = 0;
44 static volatile apr_status_t sp_erl_recv = 0;
45
46 static volatile apr_size_t sf_max_send = 0;
47 static volatile apr_size_t sf_min_send = 10000000;
48 static volatile apr_uint32_t sf_num_send = 0;
49 static volatile apr_off_t sf_tot_send = 0;
50
51 void sp_network_dump_statistics()
52 {
53 fprintf(stderr, "Network Statistics ......\n");
54 fprintf(stderr, "Sockets created : %d\n", sp_created);
55 fprintf(stderr, "Sockets accepted : %d\n", sp_accepted);
56 fprintf(stderr, "Sockets closed : %d\n", sp_closed);
57 fprintf(stderr, "Sockets cleared : %d\n", sp_cleared);
58 fprintf(stderr, "Total send calls : %d\n", sp_num_send);
59 fprintf(stderr, "Minimum send length : %d\n", sp_min_send);
60 fprintf(stderr, "Maximum send length : %d\n", sp_max_send);
61 fprintf(stderr, "Average send length : %.2f\n", (double)sp_tot_send/(dou ble)sp_num_send);
62 fprintf(stderr, "Total recv calls : %d\n", sp_num_recv);
63 fprintf(stderr, "Minimum recv length : %d\n", sp_min_recv);
64 fprintf(stderr, "Maximum recv length : %d\n", sp_max_recv);
65 fprintf(stderr, "Average recv length : %.2f\n", (double)sp_tot_recv/(dou ble)sp_num_recv);
66 fprintf(stderr, "Receive timeouts : %d\n", sp_tmo_recv);
67 fprintf(stderr, "Receive errors : %d\n", sp_err_recv);
68 fprintf(stderr, "Receive resets : %d\n", sp_rst_recv);
69 fprintf(stderr, "Last receive error : %d\n", sp_erl_recv);
70
71 fprintf(stderr, "Total sendfile calls : %d\n", sf_num_send);
72 fprintf(stderr, "Minimum sendfile length : %" APR_SIZE_T_FMT "\n", sf_min_se nd);
73 fprintf(stderr, "Maximum sendfile length : %" APR_SIZE_T_FMT "\n", sf_max_se nd);
74
75 }
76
77 #endif /* TCN_DO_STATISTICS */
78
79 extern apr_pool_t *tcn_global_pool;
80 static apr_status_t sp_socket_cleanup(void *data)
81 {
82 tcn_socket_t *s = (tcn_socket_t *)data;
83
84 if (s->net && s->net->cleanup)
85 (*s->net->cleanup)(s->opaque);
86 if (s->sock) {
87 apr_socket_t *as = s->sock;
88 s->sock = NULL;
89 apr_socket_close(as);
90 }
91 #ifdef TCN_DO_STATISTICS
92 apr_atomic_inc32(&sp_cleared);
93 #endif
94 return APR_SUCCESS;
95 }
96
97 #if defined(DEBUG) || defined(_DEBUG)
98 static APR_INLINE apr_status_t APR_THREAD_FUNC
99 APR_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
100 {
101 return apr_socket_send(sock, buf, len);
102 }
103
104 static APR_INLINE apr_status_t APR_THREAD_FUNC
105 APR_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
106 {
107 return apr_socket_recv(sock, buf, len);
108 }
109
110 static APR_INLINE apr_status_t APR_THREAD_FUNC
111 APR_socket_sendv(apr_socket_t *sock, const struct iovec *vec,
112 apr_int32_t nvec, apr_size_t *len)
113 {
114 return apr_socket_sendv(sock, vec, nvec, len);
115 }
116
117 static APR_INLINE apr_status_t APR_THREAD_FUNC
118 APR_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
119 {
120 return apr_socket_shutdown(sock, how);
121 }
122
123 static APR_INLINE apr_status_t APR_THREAD_FUNC
124 APR_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
125 {
126 return apr_socket_timeout_set(sock, t);
127 }
128
129 static APR_INLINE apr_status_t APR_THREAD_FUNC
130 APR_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
131 {
132 return apr_socket_timeout_get(sock, t);
133 }
134
135 static APR_INLINE apr_status_t APR_THREAD_FUNC
136 APR_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
137 {
138 return apr_socket_opt_set(sock, opt, on);
139 }
140
141 static APR_INLINE apr_status_t APR_THREAD_FUNC
142 APR_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
143 {
144 return apr_socket_opt_get(sock, opt, on);
145 }
146
147 #else
148 #define APR_socket_send apr_socket_send
149 #define APR_socket_recv apr_socket_recv
150 #define APR_socket_sendv apr_socket_sendv
151 #define APR_socket_shutdown apr_socket_shutdown
152 #define APR_socket_timeout_set apr_socket_timeout_set
153 #define APR_socket_timeout_get apr_socket_timeout_get
154 #define APR_socket_opt_set apr_socket_opt_set
155 #define APR_socket_opt_get apr_socket_opt_get
156 #endif
157
158 static tcn_nlayer_t apr_socket_layer = {
159 TCN_SOCKET_APR,
160 NULL,
161 NULL,
162 APR_socket_shutdown,
163 APR_socket_opt_get,
164 APR_socket_opt_set,
165 APR_socket_timeout_get,
166 APR_socket_timeout_set,
167 APR_socket_send,
168 APR_socket_sendv,
169 APR_socket_recv
170 };
171
172 TCN_IMPLEMENT_CALL(jlong, Socket, create)(TCN_STDARGS, jint family,
173 jint type, jint protocol,
174 jlong pool)
175 {
176 apr_pool_t *p = J2P(pool, apr_pool_t *);
177 apr_pool_t *c = NULL;
178 apr_socket_t *s = NULL;
179 tcn_socket_t *a = NULL;
180 apr_int32_t f, t;
181
182 UNREFERENCED(o);
183 TCN_ASSERT(pool != 0);
184 GET_S_FAMILY(f, family);
185 GET_S_TYPE(t, type);
186
187 TCN_THROW_IF_ERR(apr_pool_create(&c, p), c);
188
189 a = (tcn_socket_t *)apr_pcalloc(c, sizeof(tcn_socket_t));
190 TCN_CHECK_ALLOCATED(a);
191 TCN_THROW_IF_ERR(apr_pool_create(&a->child, c), a->child);
192 a->pool = c;
193
194 if (family >= 0) {
195 a->net = &apr_socket_layer;
196 TCN_THROW_IF_ERR(apr_socket_create(&s,
197 f, t, protocol, c), a);
198 }
199 apr_pool_cleanup_register(c, (const void *)a,
200 sp_socket_cleanup,
201 apr_pool_cleanup_null);
202
203 #ifdef TCN_DO_STATISTICS
204 sp_created++;
205 #endif
206 a->sock = s;
207 if (family >= 0)
208 a->net = &apr_socket_layer;
209 a->opaque = s;
210 return P2J(a);
211 cleanup:
212 if (c)
213 apr_pool_destroy(c);
214 return 0;
215
216 }
217
218 TCN_IMPLEMENT_CALL(void, Socket, destroy)(TCN_STDARGS, jlong sock)
219 {
220 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
221 apr_socket_t *as;
222 UNREFERENCED_STDARGS;
223 TCN_ASSERT(sock != 0);
224
225 as = s->sock;
226 s->sock = NULL;
227 apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
228 if (s->net && s->net->cleanup) {
229 (*s->net->cleanup)(s->opaque);
230 s->net = NULL;
231 }
232 if (as) {
233 apr_socket_close(as);
234 }
235
236 apr_pool_destroy(s->pool);
237 }
238
239 TCN_IMPLEMENT_CALL(jlong, Socket, pool)(TCN_STDARGS, jlong sock)
240 {
241 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
242 apr_pool_t *n;
243
244 UNREFERENCED(o);
245 TCN_ASSERT(sock != 0);
246 TCN_THROW_IF_ERR(apr_pool_create(&n, s->pool), n);
247 cleanup:
248 return P2J(n);
249 }
250
251 TCN_IMPLEMENT_CALL(jlong, Socket, get)(TCN_STDARGS, jlong sock, jint what)
252 {
253 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
254 UNREFERENCED_STDARGS;
255 TCN_ASSERT(sock != 0);
256
257 switch (what) {
258 case TCN_SOCKET_GET_POOL:
259 return P2J(s->pool);
260 break;
261 case TCN_SOCKET_GET_IMPL:
262 return P2J(s->opaque);
263 break;
264 case TCN_SOCKET_GET_APRS:
265 return P2J(s->sock);
266 break;
267 case TCN_SOCKET_GET_TYPE:
268 return (jlong)(s->net->type);
269 break;
270 }
271 return 0;
272 }
273
274 TCN_IMPLEMENT_CALL(jint, Socket, shutdown)(TCN_STDARGS, jlong sock,
275 jint how)
276 {
277 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
278
279 UNREFERENCED_STDARGS;
280 TCN_ASSERT(sock != 0);
281 return (jint)(*s->net->shutdown)(s->opaque, how);
282 }
283
284 TCN_IMPLEMENT_CALL(jint, Socket, close)(TCN_STDARGS, jlong sock)
285 {
286 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
287 jint rv = APR_SUCCESS;
288 apr_socket_t *as;
289 UNREFERENCED_STDARGS;
290 TCN_ASSERT(sock != 0);
291
292 as = s->sock;
293 s->sock = NULL;
294 apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
295 if (s->child) {
296 apr_pool_clear(s->child);
297 }
298 #ifdef TCN_DO_STATISTICS
299 apr_atomic_inc32(&sp_closed);
300 #endif
301 if (s->net && s->net->close) {
302 rv = (*s->net->close)(s->opaque);
303 s->net = NULL;
304 }
305 if (as) {
306 rv = (jint)apr_socket_close(as);
307 }
308 return rv;
309 }
310
311 TCN_IMPLEMENT_CALL(jint, Socket, bind)(TCN_STDARGS, jlong sock,
312 jlong sa)
313 {
314 jint rv = APR_SUCCESS;
315 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
316 apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);
317
318 UNREFERENCED_STDARGS;
319 TCN_ASSERT(sock != 0);
320 TCN_ASSERT(s->sock != NULL);
321 rv = (jint)apr_socket_bind(s->sock, a);
322 return rv;
323 }
324
325 TCN_IMPLEMENT_CALL(jint, Socket, listen)(TCN_STDARGS, jlong sock,
326 jint backlog)
327 {
328 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
329
330 UNREFERENCED_STDARGS;
331 TCN_ASSERT(sock != 0);
332 TCN_ASSERT(s->sock != NULL);
333 return (jint)apr_socket_listen(s->sock, backlog);
334 }
335
336 TCN_IMPLEMENT_CALL(jlong, Socket, acceptx)(TCN_STDARGS, jlong sock,
337 jlong pool)
338 {
339 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
340 apr_pool_t *p = J2P(pool, apr_pool_t *);
341 apr_socket_t *n = NULL;
342 tcn_socket_t *a = NULL;
343
344 UNREFERENCED(o);
345 TCN_ASSERT(sock != 0);
346
347 if (s->net->type == TCN_SOCKET_APR) {
348 TCN_ASSERT(s->sock != NULL);
349 a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
350 TCN_CHECK_ALLOCATED(a);
351 a->pool = p;
352 apr_pool_cleanup_register(a->pool, (const void *)a,
353 sp_socket_cleanup,
354 apr_pool_cleanup_null);
355
356 TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
357 }
358 else {
359 tcn_ThrowAPRException(e, APR_ENOTIMPL);
360 goto cleanup;
361 }
362 if (n) {
363 #ifdef TCN_DO_STATISTICS
364 apr_atomic_inc32(&sp_accepted);
365 #endif
366 a->net = &apr_socket_layer;
367 a->sock = n;
368 a->opaque = n;
369 }
370
371 cleanup:
372 return P2J(a);
373 }
374
375 TCN_IMPLEMENT_CALL(jlong, Socket, accept)(TCN_STDARGS, jlong sock)
376 {
377 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
378 apr_pool_t *p = NULL;
379 apr_socket_t *n = NULL;
380 tcn_socket_t *a = NULL;
381
382 UNREFERENCED(o);
383 TCN_ASSERT(sock != 0);
384
385 TCN_THROW_IF_ERR(apr_pool_create(&p, s->child), p);
386 if (s->net->type == TCN_SOCKET_APR) {
387 TCN_ASSERT(s->sock != NULL);
388 a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
389 TCN_CHECK_ALLOCATED(a);
390 TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
391
392 a->pool = p;
393 apr_pool_cleanup_register(a->pool, (const void *)a,
394 sp_socket_cleanup,
395 apr_pool_cleanup_null);
396
397 }
398 else {
399 tcn_ThrowAPRException(e, APR_ENOTIMPL);
400 goto cleanup;
401 }
402 if (n) {
403 #ifdef TCN_DO_STATISTICS
404 apr_atomic_inc32(&sp_accepted);
405 #endif
406 a->net = &apr_socket_layer;
407 a->sock = n;
408 a->opaque = n;
409 }
410 return P2J(a);
411 cleanup:
412 if (tcn_global_pool && p && s->sock)
413 apr_pool_destroy(p);
414 return 0;
415 }
416
417 TCN_IMPLEMENT_CALL(jint, Socket, connect)(TCN_STDARGS, jlong sock,
418 jlong sa)
419 {
420 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
421 apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);
422
423 UNREFERENCED_STDARGS;
424 TCN_ASSERT(sock != 0);
425 TCN_ASSERT(s->sock != NULL);
426 return (jint)apr_socket_connect(s->sock, a);
427 }
428
429 TCN_IMPLEMENT_CALL(jint, Socket, send)(TCN_STDARGS, jlong sock,
430 jbyteArray buf, jint offset, jint tosend)
431 {
432 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
433 apr_size_t nbytes = (apr_size_t)tosend;
434 apr_status_t ss;
435
436 UNREFERENCED(o);
437 if (!sock) {
438 tcn_ThrowAPRException(e, APR_ENOTSOCK);
439 return -(jint)APR_ENOTSOCK;
440 }
441 TCN_ASSERT(s->opaque != NULL);
442 if(!s->net) {
443 tcn_ThrowAPRException(e, APR_EINVALSOCK);
444 return -(jint)APR_EINVALSOCK;
445 }
446 #ifdef TCN_DO_STATISTICS
447 sp_max_send = TCN_MAX(sp_max_send, nbytes);
448 sp_min_send = TCN_MIN(sp_min_send, nbytes);
449 sp_tot_send += nbytes;
450 sp_num_send++;
451 #endif
452
453 if (tosend <= TCN_BUFFER_SZ) {
454 jbyte sb[TCN_BUFFER_SZ];
455 (*e)->GetByteArrayRegion(e, buf, offset, tosend, &sb[0]);
456 ss = (*s->net->send)(s->opaque, (const char *)&sb[0], &nbytes);
457 }
458 else {
459 jbyte *sb = (jbyte *)malloc(nbytes);
460 if (sb == NULL)
461 return -APR_ENOMEM;
462 (*e)->GetByteArrayRegion(e, buf, offset, tosend, sb);
463 ss = (*s->net->send)(s->opaque, (const char *)sb, &nbytes);
464 free(sb);
465 }
466 if (ss == APR_SUCCESS || ((APR_STATUS_IS_EAGAIN(ss) || ss == TCN_EAGAIN) && nbytes > 0))
467 return (jint)nbytes;
468 else {
469 TCN_ERROR_WRAP(ss);
470 return -(jint)ss;
471 }
472 }
473
474 TCN_IMPLEMENT_CALL(void, Socket, setsbb)(TCN_STDARGS, jlong sock,
475 jobject buf)
476 {
477 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
478 UNREFERENCED(o);
479 if (!sock) {
480 tcn_ThrowAPRException(e, APR_ENOTSOCK);
481 return;
482 }
483 TCN_ASSERT(s->opaque != NULL);
484 if (buf)
485 s->jsbbuff = (char *)(*e)->GetDirectBufferAddress(e, buf);
486 else
487 s->jsbbuff = NULL;
488 }
489
490 TCN_IMPLEMENT_CALL(void, Socket, setrbb)(TCN_STDARGS, jlong sock,
491 jobject buf)
492 {
493 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
494 UNREFERENCED(o);
495 if (!sock) {
496 tcn_ThrowAPRException(e, APR_ENOTSOCK);
497 return;
498 }
499 TCN_ASSERT(s->opaque != NULL);
500 if (buf)
501 s->jrbbuff = (char *)(*e)->GetDirectBufferAddress(e, buf);
502 else
503 s->jrbbuff = NULL;
504 }
505
506 TCN_IMPLEMENT_CALL(jint, Socket, sendb)(TCN_STDARGS, jlong sock,
507 jobject buf, jint offset, jint len)
508 {
509 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
510 apr_size_t nbytes = (apr_size_t)len;
511 apr_size_t sent = 0;
512 char *bytes;
513 apr_status_t ss = APR_SUCCESS;
514
515 UNREFERENCED(o);
516 if (!sock) {
517 tcn_ThrowAPRException(e, APR_ENOTSOCK);
518 return -(jint)APR_ENOTSOCK;
519 }
520 TCN_ASSERT(s->opaque != NULL);
521 TCN_ASSERT(buf != NULL);
522 if(!s->net) {
523 tcn_ThrowAPRException(e, APR_EINVALSOCK);
524 return -(jint)APR_EINVALSOCK;
525 }
526 #ifdef TCN_DO_STATISTICS
527 sp_max_send = TCN_MAX(sp_max_send, nbytes);
528 sp_min_send = TCN_MIN(sp_min_send, nbytes);
529 sp_tot_send += nbytes;
530 sp_num_send++;
531 #endif
532
533 bytes = (char *)(*e)->GetDirectBufferAddress(e, buf);
534
535 while (sent < nbytes) {
536 apr_size_t wr = nbytes - sent;
537 ss = (*s->net->send)(s->opaque, bytes + offset + sent, &wr);
538 if (ss != APR_SUCCESS)
539 break;
540 sent += wr;
541 }
542
543 if (ss == APR_SUCCESS || ((APR_STATUS_IS_EAGAIN(ss) || ss == TCN_EAGAIN) && sent > 0))
544 return (jint)sent;
545 else {
546 TCN_ERROR_WRAP(ss);
547 return -(jint)ss;
548 }
549 }
550
551 TCN_IMPLEMENT_CALL(jint, Socket, sendib)(TCN_STDARGS, jlong sock,
552 jobject buf, jint offset, jint len)
553 {
554 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
555 apr_size_t nbytes = (apr_size_t)len;
556 char *bytes;
557 apr_status_t ss = APR_SUCCESS;
558
559 UNREFERENCED(o);
560 if (!sock) {
561 tcn_ThrowAPRException(e, APR_ENOTSOCK);
562 return -(jint)APR_ENOTSOCK;
563 }
564 TCN_ASSERT(s->opaque != NULL);
565 TCN_ASSERT(buf != NULL);
566 if(!s->net) {
567 tcn_ThrowAPRException(e, APR_EINVALSOCK);
568 return -(jint)APR_EINVALSOCK;
569 }
570 #ifdef TCN_DO_STATISTICS
571 sp_max_send = TCN_MAX(sp_max_send, nbytes);
572 sp_min_send = TCN_MIN(sp_min_send, nbytes);
573 sp_tot_send += nbytes;
574 sp_num_send++;
575 #endif
576
577 bytes = (char *)(*e)->GetDirectBufferAddress(e, buf);
578
579 ss = (*s->net->send)(s->opaque, bytes + offset, &nbytes);
580
581 if (ss == APR_SUCCESS || ((APR_STATUS_IS_EAGAIN(ss) || ss == TCN_EAGAIN) && nbytes > 0))
582 return (jint)nbytes;
583 else {
584 TCN_ERROR_WRAP(ss);
585 return -(jint)ss;
586 }
587 }
588
589 TCN_IMPLEMENT_CALL(jint, Socket, sendbb)(TCN_STDARGS, jlong sock,
590 jint offset, jint len)
591 {
592 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
593 apr_size_t nbytes = (apr_size_t)len;
594 apr_size_t sent = 0;
595 apr_status_t ss = APR_SUCCESS;
596
597 UNREFERENCED(o);
598 if (!sock) {
599 tcn_ThrowAPRException(e, APR_ENOTSOCK);
600 return -(jint)APR_ENOTSOCK;
601 }
602 TCN_ASSERT(s->opaque != NULL);
603 TCN_ASSERT(s->jsbbuff != NULL);
604 if(!s->net) {
605 tcn_ThrowAPRException(e, APR_EINVALSOCK);
606 return -(jint)APR_EINVALSOCK;
607 }
608 #ifdef TCN_DO_STATISTICS
609 sp_max_send = TCN_MAX(sp_max_send, nbytes);
610 sp_min_send = TCN_MIN(sp_min_send, nbytes);
611 sp_tot_send += nbytes;
612 sp_num_send++;
613 #endif
614
615 while (sent < nbytes) {
616 apr_size_t wr = nbytes - sent;
617 ss = (*s->net->send)(s->opaque, s->jsbbuff + offset + sent, &wr);
618 if (ss != APR_SUCCESS || wr == 0)
619 break;
620 sent += wr;
621 }
622 if (ss == APR_SUCCESS || ((APR_STATUS_IS_EAGAIN(ss) || ss == TCN_EAGAIN) && sent > 0))
623 return (jint)sent;
624 else {
625 TCN_ERROR_WRAP(ss);
626 return -(jint)ss;
627 }
628 }
629
630 TCN_IMPLEMENT_CALL(jint, Socket, sendibb)(TCN_STDARGS, jlong sock,
631 jint offset, jint len)
632 {
633 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
634 apr_size_t nbytes = (apr_size_t)len;
635 apr_status_t ss = APR_SUCCESS;
636
637 UNREFERENCED(o);
638 if (!sock) {
639 tcn_ThrowAPRException(e, APR_ENOTSOCK);
640 return -(jint)APR_ENOTSOCK;
641 }
642 TCN_ASSERT(s->opaque != NULL);
643 TCN_ASSERT(s->jsbbuff != NULL);
644 if(!s->net) {
645 tcn_ThrowAPRException(e, APR_EINVALSOCK);
646 return -(jint)APR_EINVALSOCK;
647 }
648 #ifdef TCN_DO_STATISTICS
649 sp_max_send = TCN_MAX(sp_max_send, nbytes);
650 sp_min_send = TCN_MIN(sp_min_send, nbytes);
651 sp_tot_send += nbytes;
652 sp_num_send++;
653 #endif
654
655 ss = (*s->net->send)(s->opaque, s->jsbbuff + offset, &nbytes);
656
657 if (ss == APR_SUCCESS || ((APR_STATUS_IS_EAGAIN(ss) || ss == TCN_EAGAIN) && nbytes > 0))
658 return (jint)nbytes;
659 else {
660 TCN_ERROR_WRAP(ss);
661 return -(jint)ss;
662 }
663 }
664
665 TCN_IMPLEMENT_CALL(jint, Socket, sendv)(TCN_STDARGS, jlong sock,
666 jobjectArray bufs)
667 {
668 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
669 jsize nvec;
670 jsize i;
671 struct iovec vec[APR_MAX_IOVEC_SIZE];
672 jobject ba[APR_MAX_IOVEC_SIZE];
673 apr_size_t written = 0;
674 apr_status_t ss;
675
676 UNREFERENCED(o);
677 TCN_ASSERT(sock != 0);
678 TCN_ASSERT(s->opaque != NULL);
679 if(!s->net) {
680 tcn_ThrowAPRException(e, APR_EINVALSOCK);
681 return -(jint)APR_EINVALSOCK;
682 }
683
684 nvec = (*e)->GetArrayLength(e, bufs);
685 if (nvec >= APR_MAX_IOVEC_SIZE)
686 return (jint)(-APR_ENOMEM);
687
688 for (i = 0; i < nvec; i++) {
689 ba[i] = (*e)->GetObjectArrayElement(e, bufs, i);
690 vec[i].iov_len = (*e)->GetArrayLength(e, ba[i]);
691 vec[i].iov_base = (void *)((*e)->GetByteArrayElements(e, ba[i], NULL));
692 }
693
694 ss = (*s->net->sendv)(s->opaque, vec, nvec, &written);
695
696 for (i = 0; i < nvec; i++) {
697 (*e)->ReleaseByteArrayElements(e, ba[i], (jbyte*)vec[i].iov_base, JNI_AB ORT);
698 }
699 if (ss == APR_SUCCESS || ((APR_STATUS_IS_EAGAIN(ss) || ss == TCN_EAGAIN) && written > 0))
700 return (jint)written;
701 else {
702 TCN_ERROR_WRAP(ss);
703 return -(jint)ss;
704 }
705 }
706
707 TCN_IMPLEMENT_CALL(jint, Socket, sendto)(TCN_STDARGS, jlong sock,
708 jlong where, jint flag,
709 jbyteArray buf, jint offset, jint tosen d)
710 {
711 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
712 apr_sockaddr_t *w = J2P(where, apr_sockaddr_t *);
713 apr_size_t nbytes = (apr_size_t)tosend;
714 jbyte *bytes;
715 apr_int32_t nb;
716 apr_status_t ss;
717
718 UNREFERENCED(o);
719 TCN_ASSERT(sock != 0);
720 TCN_ASSERT(s->sock != NULL);
721
722 apr_socket_opt_get(s->sock, APR_SO_NONBLOCK, &nb);
723 if (nb)
724 bytes = (*e)->GetPrimitiveArrayCritical(e, buf, NULL);
725 else
726 bytes = (*e)->GetByteArrayElements(e, buf, NULL);
727 TCN_ASSERT(bytes != NULL);
728 ss = apr_socket_sendto(s->sock, w, flag, (char *)(bytes + offset), &nbytes);
729
730 if (nb)
731 (*e)->ReleasePrimitiveArrayCritical(e, buf, bytes, 0);
732 else
733 (*e)->ReleaseByteArrayElements(e, buf, bytes, JNI_ABORT);
734 if (ss == APR_SUCCESS)
735 return (jint)nbytes;
736 else {
737 TCN_ERROR_WRAP(ss);
738 return -(jint)ss;
739 }
740 }
741
742 TCN_IMPLEMENT_CALL(jint, Socket, recv)(TCN_STDARGS, jlong sock,
743 jbyteArray buf, jint offset, jint toread)
744 {
745 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
746 apr_size_t nbytes = (apr_size_t)toread;
747 apr_status_t ss;
748
749 UNREFERENCED(o);
750 TCN_ASSERT(sock != 0);
751 TCN_ASSERT(s->opaque != NULL);
752 if(!s->net) {
753 tcn_ThrowAPRException(e, APR_EINVALSOCK);
754 return -(jint)APR_EINVALSOCK;
755 }
756
757 if (toread <= TCN_BUFFER_SZ) {
758 char sb[TCN_BUFFER_SZ];
759
760 if ((ss = (*s->net->recv)(s->opaque, sb, &nbytes)) == APR_SUCCESS)
761 (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, (jbyte*)&sb[ 0]);
762 }
763 else {
764 jbyte *bytes = (*e)->GetByteArrayElements(e, buf, NULL);
765 if ((ss = (*s->net->recv)(s->opaque, (char*)(bytes + offset),
766 &nbytes)) == APR_SUCCESS)
767 (*e)->ReleaseByteArrayElements(e, buf, bytes,
768 nbytes ? 0 : JNI_ABORT);
769 }
770 #ifdef TCN_DO_STATISTICS
771 if (ss == APR_SUCCESS) {
772 sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
773 sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
774 sp_tot_recv += nbytes;
775 sp_num_recv++;
776 }
777 else {
778 if (APR_STATUS_IS_ETIMEDOUT(ss) ||
779 APR_STATUS_IS_TIMEUP(ss))
780 sp_tmo_recv++;
781 else if (APR_STATUS_IS_ECONNABORTED(ss) ||
782 APR_STATUS_IS_ECONNRESET(ss) ||
783 APR_STATUS_IS_EOF(ss))
784 sp_rst_recv++;
785 else {
786 sp_err_recv++;
787 sp_erl_recv = ss;
788 }
789 }
790 #endif
791 if (ss == APR_SUCCESS)
792 return (jint)nbytes;
793 else {
794 TCN_ERROR_WRAP(ss);
795 return -(jint)ss;
796 }
797 }
798
799 TCN_IMPLEMENT_CALL(jint, Socket, recvt)(TCN_STDARGS, jlong sock,
800 jbyteArray buf, jint offset,
801 jint toread, jlong timeout)
802 {
803 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
804 apr_size_t nbytes = (apr_size_t)toread;
805 apr_status_t ss;
806 apr_interval_time_t pt;
807 apr_interval_time_t nt = J2T(timeout);
808
809 UNREFERENCED(o);
810 TCN_ASSERT(sock != 0);
811 TCN_ASSERT(s->opaque != NULL);
812 TCN_ASSERT(buf != NULL);
813 if(!s->net) {
814 tcn_ThrowAPRException(e, APR_EINVALSOCK);
815 return -(jint)APR_EINVALSOCK;
816 }
817
818 if ((ss = (*s->net->timeout_get)(s->opaque, &pt)) != APR_SUCCESS) {
819 TCN_ERROR_WRAP(ss);
820 return -(jint)ss;
821 }
822 if (pt != nt) {
823 if ((ss = (*s->net->timeout_set)(s->opaque, nt)) != APR_SUCCESS)
824 goto cleanup;
825 }
826 if (toread <= TCN_BUFFER_SZ) {
827 jbyte sb[TCN_BUFFER_SZ];
828 if ((ss = (*s->net->recv)(s->opaque, (char *)&sb[0], &nbytes)) == APR_SU CCESS)
829 (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, &sb[0]);
830 }
831 else {
832 jbyte *sb = (jbyte *)malloc(nbytes);
833 if (sb == NULL)
834 return -APR_ENOMEM;
835 if ((ss = (*s->net->recv)(s->opaque, (char *)sb, &nbytes)) == APR_SUCCES S)
836 (*e)->SetByteArrayRegion(e, buf, offset, (jsize)nbytes, &sb[0]);
837 free(sb);
838 }
839 if (pt != nt) {
840 if ((ss = (*s->net->timeout_set)(s->opaque, pt)) != APR_SUCCESS)
841 goto cleanup;
842 }
843
844 #ifdef TCN_DO_STATISTICS
845 if (ss == APR_SUCCESS) {
846 sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
847 sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
848 sp_tot_recv += nbytes;
849 sp_num_recv++;
850 }
851 else {
852 if (APR_STATUS_IS_ETIMEDOUT(ss) ||
853 APR_STATUS_IS_TIMEUP(ss))
854 sp_tmo_recv++;
855 else if (APR_STATUS_IS_ECONNABORTED(ss) ||
856 APR_STATUS_IS_ECONNRESET(ss) ||
857 APR_STATUS_IS_EOF(ss))
858 sp_rst_recv++;
859 else {
860 sp_err_recv++;
861 sp_erl_recv = ss;
862 }
863 }
864 #endif
865 cleanup:
866 if (ss == APR_SUCCESS)
867 return (jint)nbytes;
868 else {
869 TCN_ERROR_WRAP(ss);
870 return -(jint)ss;
871 }
872 }
873
874 TCN_IMPLEMENT_CALL(jint, Socket, recvb)(TCN_STDARGS, jlong sock,
875 jobject buf, jint offset, jint len)
876 {
877 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
878 apr_status_t ss;
879 apr_size_t nbytes = (apr_size_t)len;
880 char *bytes;
881
882 UNREFERENCED(o);
883 if (!sock) {
884 tcn_ThrowAPRException(e, APR_ENOTSOCK);
885 return -(jint)APR_ENOTSOCK;
886 }
887 TCN_ASSERT(s->opaque != NULL);
888 TCN_ASSERT(buf != NULL);
889 if(!s->net) {
890 tcn_ThrowAPRException(e, APR_EINVALSOCK);
891 return -(jint)APR_EINVALSOCK;
892 }
893
894 bytes = (char *)(*e)->GetDirectBufferAddress(e, buf);
895 TCN_ASSERT(bytes != NULL);
896 ss = (*s->net->recv)(s->opaque, bytes + offset, &nbytes);
897 #ifdef TCN_DO_STATISTICS
898 if (ss == APR_SUCCESS) {
899 sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
900 sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
901 sp_tot_recv += nbytes;
902 sp_num_recv++;
903 }
904 else {
905 if (APR_STATUS_IS_ETIMEDOUT(ss) ||
906 APR_STATUS_IS_TIMEUP(ss))
907 sp_tmo_recv++;
908 else if (APR_STATUS_IS_ECONNABORTED(ss) ||
909 APR_STATUS_IS_ECONNRESET(ss) ||
910 APR_STATUS_IS_EOF(ss))
911 sp_rst_recv++;
912 else {
913 sp_err_recv++;
914 sp_erl_recv = ss;
915 }
916 }
917 #endif
918 if (ss == APR_SUCCESS)
919 return (jint)nbytes;
920 else {
921 TCN_ERROR_WRAP(ss);
922 return -(jint)ss;
923 }
924 }
925
926 TCN_IMPLEMENT_CALL(jint, Socket, recvbb)(TCN_STDARGS, jlong sock,
927 jint offset, jint len)
928 {
929 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
930 apr_status_t ss;
931 apr_size_t nbytes = (apr_size_t)len;
932
933 UNREFERENCED(o);
934 if (!sock) {
935 tcn_ThrowAPRException(e, APR_ENOTSOCK);
936 return -(jint)APR_ENOTSOCK;
937 }
938 TCN_ASSERT(sock != 0);
939 TCN_ASSERT(s->opaque != NULL);
940 TCN_ASSERT(s->jrbbuff != NULL);
941 if(!s->net) {
942 tcn_ThrowAPRException(e, APR_EINVALSOCK);
943 return -(jint)APR_EINVALSOCK;
944 }
945
946 ss = (*s->net->recv)(s->opaque, s->jrbbuff + offset, &nbytes);
947 #ifdef TCN_DO_STATISTICS
948 if (ss == APR_SUCCESS) {
949 sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
950 sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
951 sp_tot_recv += nbytes;
952 sp_num_recv++;
953 }
954 else {
955 if (APR_STATUS_IS_ETIMEDOUT(ss) ||
956 APR_STATUS_IS_TIMEUP(ss))
957 sp_tmo_recv++;
958 else if (APR_STATUS_IS_ECONNABORTED(ss) ||
959 APR_STATUS_IS_ECONNRESET(ss) ||
960 APR_STATUS_IS_EOF(ss))
961 sp_rst_recv++;
962 else {
963 sp_err_recv++;
964 sp_erl_recv = ss;
965 }
966 }
967 #endif
968 if (ss == APR_SUCCESS)
969 return (jint)nbytes;
970 else if (APR_STATUS_IS_EOF(ss))
971 return 0;
972 else {
973 TCN_ERROR_WRAP(ss);
974 return -(jint)ss;
975 }
976 }
977
978 TCN_IMPLEMENT_CALL(jint, Socket, recvbt)(TCN_STDARGS, jlong sock,
979 jobject buf, jint offset,
980 jint len, jlong timeout)
981 {
982 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
983 apr_status_t ss;
984 apr_size_t nbytes = (apr_size_t)len;
985 char *bytes;
986 apr_interval_time_t pt;
987 apr_interval_time_t nt = J2T(timeout);
988
989 UNREFERENCED(o);
990 if (!sock) {
991 tcn_ThrowAPRException(e, APR_ENOTSOCK);
992 return -(jint)APR_ENOTSOCK;
993 }
994 TCN_ASSERT(buf != NULL);
995 TCN_ASSERT(s->opaque != NULL);
996 if(!s->net) {
997 tcn_ThrowAPRException(e, APR_EINVALSOCK);
998 return -(jint)APR_EINVALSOCK;
999 }
1000
1001 bytes = (char *)(*e)->GetDirectBufferAddress(e, buf);
1002 TCN_ASSERT(bytes != NULL);
1003
1004 if ((ss = (*s->net->timeout_get)(s->opaque, &pt)) != APR_SUCCESS) {
1005 TCN_ERROR_WRAP(ss);
1006 return -(jint)ss;
1007 }
1008 if (pt != nt) {
1009 if ((ss = (*s->net->timeout_set)(s->opaque, nt)) != APR_SUCCESS) {
1010 TCN_ERROR_WRAP(ss);
1011 return -(jint)ss;
1012 }
1013 }
1014 ss = (*s->net->recv)(s->opaque, bytes + offset, &nbytes);
1015 if (pt != nt) {
1016 if ((ss = (*s->net->timeout_set)(s->opaque, pt)) != APR_SUCCESS) {
1017 TCN_ERROR_WRAP(ss);
1018 return -(jint)ss;
1019 }
1020 }
1021
1022 #ifdef TCN_DO_STATISTICS
1023 if (ss == APR_SUCCESS) {
1024 sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
1025 sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
1026 sp_tot_recv += nbytes;
1027 sp_num_recv++;
1028 }
1029 else {
1030 if (APR_STATUS_IS_ETIMEDOUT(ss) ||
1031 APR_STATUS_IS_TIMEUP(ss))
1032 sp_tmo_recv++;
1033 else if (APR_STATUS_IS_ECONNABORTED(ss) ||
1034 APR_STATUS_IS_ECONNRESET(ss) ||
1035 APR_STATUS_IS_EOF(ss))
1036 sp_rst_recv++;
1037 else {
1038 sp_err_recv++;
1039 sp_erl_recv = ss;
1040 }
1041 }
1042 #endif
1043 if (ss == APR_SUCCESS)
1044 return (jint)nbytes;
1045 else {
1046 TCN_ERROR_WRAP(ss);
1047 return -(jint)ss;
1048 }
1049 }
1050
1051 TCN_IMPLEMENT_CALL(jint, Socket, recvbbt)(TCN_STDARGS, jlong sock,
1052 jint offset,
1053 jint len, jlong timeout)
1054 {
1055 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1056 apr_status_t ss;
1057 apr_size_t nbytes = (apr_size_t)len;
1058 apr_interval_time_t pt;
1059 apr_interval_time_t nt = J2T(timeout);
1060
1061 UNREFERENCED_STDARGS;
1062 UNREFERENCED(o);
1063 if (!sock) {
1064 tcn_ThrowAPRException(e, APR_ENOTSOCK);
1065 return -(jint)APR_ENOTSOCK;
1066 }
1067 TCN_ASSERT(s->jrbbuff != NULL);
1068 TCN_ASSERT(s->opaque != NULL);
1069 if(!s->net) {
1070 tcn_ThrowAPRException(e, APR_EINVALSOCK);
1071 return -(jint)APR_EINVALSOCK;
1072 }
1073
1074 if ((ss = (*s->net->timeout_get)(s->opaque, &pt)) != APR_SUCCESS) {
1075 TCN_ERROR_WRAP(ss);
1076 return -(jint)ss;
1077 }
1078 if (pt != nt) {
1079 if ((ss = (*s->net->timeout_set)(s->opaque, nt)) != APR_SUCCESS) {
1080 TCN_ERROR_WRAP(ss);
1081 return -(jint)ss;
1082 }
1083 }
1084 ss = (*s->net->recv)(s->opaque, s->jrbbuff + offset, &nbytes);
1085 if (pt != nt) {
1086 if ((ss = (*s->net->timeout_set)(s->opaque, pt)) != APR_SUCCESS) {
1087 TCN_ERROR_WRAP(ss);
1088 return -(jint)ss;
1089 }
1090 }
1091
1092 #ifdef TCN_DO_STATISTICS
1093 if (ss == APR_SUCCESS) {
1094 sp_max_recv = TCN_MAX(sp_max_recv, nbytes);
1095 sp_min_recv = TCN_MIN(sp_min_recv, nbytes);
1096 sp_tot_recv += nbytes;
1097 sp_num_recv++;
1098 }
1099 else {
1100 if (APR_STATUS_IS_ETIMEDOUT(ss) ||
1101 APR_STATUS_IS_TIMEUP(ss))
1102 sp_tmo_recv++;
1103 else if (APR_STATUS_IS_ECONNABORTED(ss) ||
1104 APR_STATUS_IS_ECONNRESET(ss) ||
1105 APR_STATUS_IS_EOF(ss))
1106 sp_rst_recv++;
1107 else {
1108 sp_err_recv++;
1109 sp_erl_recv = ss;
1110 }
1111 }
1112 #endif
1113 if (ss == APR_SUCCESS)
1114 return (jint)nbytes;
1115 else {
1116 TCN_ERROR_WRAP(ss);
1117 return -(jint)ss;
1118 }
1119 }
1120
1121 TCN_IMPLEMENT_CALL(jint, Socket, recvfrom)(TCN_STDARGS, jlong from,
1122 jlong sock, jint flags,
1123 jbyteArray buf, jint offset, jint tore ad)
1124 {
1125 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1126 apr_sockaddr_t *f = J2P(from, apr_sockaddr_t *);
1127 apr_size_t nbytes = (apr_size_t)toread;
1128 jbyte *bytes = (*e)->GetByteArrayElements(e, buf, NULL);
1129 apr_status_t ss;
1130
1131 UNREFERENCED(o);
1132 if (!sock) {
1133 tcn_ThrowAPRException(e, APR_ENOTSOCK);
1134 return -(jint)APR_ENOTSOCK;
1135 }
1136 TCN_ASSERT(s->sock != NULL);
1137 TCN_ASSERT(buf != NULL);
1138 ss = apr_socket_recvfrom(f, s->sock, (apr_int32_t)flags, (char*)(bytes + off set), &nbytes);
1139
1140 (*e)->ReleaseByteArrayElements(e, buf, bytes,
1141 nbytes ? 0 : JNI_ABORT);
1142 if (ss == APR_SUCCESS)
1143 return (jint)nbytes;
1144 else {
1145 TCN_ERROR_WRAP(ss);
1146 return -(jint)ss;
1147 }
1148 }
1149
1150 TCN_IMPLEMENT_CALL(jint, Socket, optSet)(TCN_STDARGS, jlong sock,
1151 jint opt, jint on)
1152 {
1153 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1154
1155 UNREFERENCED(o);
1156 if (!s->sock) {
1157 return APR_ENOTSOCK;
1158 }
1159 else
1160 return (jint)(*s->net->opt_set)(s->opaque, (apr_int32_t)opt, (apr_int32_ t)on);
1161 }
1162
1163 TCN_IMPLEMENT_CALL(jint, Socket, optGet)(TCN_STDARGS, jlong sock,
1164 jint opt)
1165 {
1166 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1167 apr_int32_t on = 0;
1168
1169 UNREFERENCED(o);
1170 if (!s->sock)
1171 tcn_ThrowAPRException(e, APR_ENOTSOCK);
1172 else {
1173 TCN_THROW_IF_ERR((*s->net->opt_get)(s->opaque, (apr_int32_t)opt,
1174 &on), on);
1175 }
1176 cleanup:
1177 return (jint)on;
1178 }
1179
1180 TCN_IMPLEMENT_CALL(jint, Socket, timeoutSet)(TCN_STDARGS, jlong sock,
1181 jlong timeout)
1182 {
1183 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1184
1185 UNREFERENCED(o);
1186 TCN_ASSERT(s->opaque != NULL);
1187 if (!sock) {
1188 tcn_ThrowAPRException(e, APR_ENOTSOCK);
1189 return APR_ENOTSOCK;
1190 }
1191 return (jint)(*s->net->timeout_set)(s->opaque, J2T(timeout));
1192 }
1193
1194 TCN_IMPLEMENT_CALL(jlong, Socket, timeoutGet)(TCN_STDARGS, jlong sock)
1195 {
1196 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1197 apr_interval_time_t timeout;
1198
1199 UNREFERENCED(o);
1200 if (!sock) {
1201 tcn_ThrowAPRException(e, APR_ENOTSOCK);
1202 return 0;
1203 }
1204 TCN_ASSERT(s->opaque != NULL);
1205
1206 TCN_THROW_IF_ERR((*s->net->timeout_get)(s->opaque, &timeout), timeout);
1207 cleanup:
1208 return (jlong)timeout;
1209 }
1210
1211 TCN_IMPLEMENT_CALL(jboolean, Socket, atmark)(TCN_STDARGS, jlong sock)
1212 {
1213 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1214 apr_int32_t mark;
1215
1216 UNREFERENCED_STDARGS;
1217 TCN_ASSERT(sock != 0);
1218 TCN_ASSERT(s->sock != NULL);
1219
1220 if (apr_socket_atmark(s->sock, &mark) != APR_SUCCESS)
1221 return JNI_FALSE;
1222 return mark ? JNI_TRUE : JNI_FALSE;
1223 }
1224
1225 #if APR_HAS_SENDFILE
1226
1227 TCN_IMPLEMENT_CALL(jlong, Socket, sendfile)(TCN_STDARGS, jlong sock,
1228 jlong file,
1229 jobjectArray headers,
1230 jobjectArray trailers,
1231 jlong offset, jlong len,
1232 jint flags)
1233 {
1234 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1235 apr_file_t *f = J2P(file, apr_file_t *);
1236 jsize nh = 0;
1237 jsize nt = 0;
1238 jsize i;
1239 struct iovec hvec[APR_MAX_IOVEC_SIZE];
1240 struct iovec tvec[APR_MAX_IOVEC_SIZE];
1241 jobject hba[APR_MAX_IOVEC_SIZE];
1242 jobject tba[APR_MAX_IOVEC_SIZE];
1243 apr_off_t off = (apr_off_t)offset;
1244 apr_size_t written = (apr_size_t)len;
1245 apr_hdtr_t hdrs;
1246 apr_status_t ss;
1247
1248 UNREFERENCED(o);
1249 TCN_ASSERT(sock != 0);
1250 TCN_ASSERT(file != 0);
1251
1252 if (s->net->type != TCN_SOCKET_APR)
1253 return (jint)(-APR_ENOTIMPL);
1254 if (headers)
1255 nh = (*e)->GetArrayLength(e, headers);
1256 if (trailers)
1257 nt = (*e)->GetArrayLength(e, trailers);
1258 /* Check for overflow */
1259 if (nh >= APR_MAX_IOVEC_SIZE || nt >= APR_MAX_IOVEC_SIZE)
1260 return (jint)(-APR_ENOMEM);
1261
1262 for (i = 0; i < nh; i++) {
1263 hba[i] = (*e)->GetObjectArrayElement(e, headers, i);
1264 hvec[i].iov_len = (*e)->GetArrayLength(e, hba[i]);
1265 hvec[i].iov_base = (void *)((*e)->GetByteArrayElements(e, hba[i], NULL)) ;
1266 }
1267 for (i = 0; i < nt; i++) {
1268 tba[i] = (*e)->GetObjectArrayElement(e, trailers, i);
1269 tvec[i].iov_len = (*e)->GetArrayLength(e, tba[i]);
1270 tvec[i].iov_base = (void *)((*e)->GetByteArrayElements(e, tba[i], NULL)) ;
1271 }
1272 hdrs.headers = &hvec[0];
1273 hdrs.numheaders = nh;
1274 hdrs.trailers = &tvec[0];
1275 hdrs.numtrailers = nt;
1276
1277
1278 ss = apr_socket_sendfile(s->sock, f, &hdrs, &off, &written, (apr_int32_t)fla gs);
1279
1280 #ifdef TCN_DO_STATISTICS
1281 sf_max_send = TCN_MAX(sf_max_send, written);
1282 sf_min_send = TCN_MIN(sf_min_send, written);
1283 sf_tot_send += written;
1284 sf_num_send++;
1285 #endif
1286
1287 for (i = 0; i < nh; i++) {
1288 (*e)->ReleaseByteArrayElements(e, hba[i], (jbyte*)hvec[i].iov_base, JNI_ ABORT);
1289 }
1290
1291 for (i = 0; i < nt; i++) {
1292 (*e)->ReleaseByteArrayElements(e, tba[i], (jbyte*)tvec[i].iov_base, JNI_ ABORT);
1293 }
1294 /* Return Number of bytes actually sent,
1295 * including headers, file, and trailers
1296 */
1297 if (ss == APR_SUCCESS)
1298 return (jlong)written;
1299 else {
1300 TCN_ERROR_WRAP(ss);
1301 return -(jlong)ss;
1302 }
1303 }
1304
1305 TCN_IMPLEMENT_CALL(jlong, Socket, sendfilen)(TCN_STDARGS, jlong sock,
1306 jlong file,
1307 jlong offset, jlong len,
1308 jint flags)
1309 {
1310 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1311 apr_file_t *f = J2P(file, apr_file_t *);
1312 apr_off_t off = (apr_off_t)offset;
1313 apr_size_t written = (apr_size_t)len;
1314 apr_hdtr_t hdrs;
1315 apr_status_t ss;
1316
1317 UNREFERENCED_STDARGS;
1318 TCN_ASSERT(sock != 0);
1319 TCN_ASSERT(file != 0);
1320
1321 if (s->net->type != TCN_SOCKET_APR)
1322 return (jint)(-APR_ENOTIMPL);
1323
1324 hdrs.headers = NULL;
1325 hdrs.numheaders = 0;
1326 hdrs.trailers = NULL;
1327 hdrs.numtrailers = 0;
1328
1329
1330 ss = apr_socket_sendfile(s->sock, f, &hdrs, &off, &written, (apr_int32_t)fla gs);
1331
1332 #ifdef TCN_DO_STATISTICS
1333 sf_max_send = TCN_MAX(sf_max_send, written);
1334 sf_min_send = TCN_MIN(sf_min_send, written);
1335 sf_tot_send += written;
1336 sf_num_send++;
1337 #endif
1338
1339 /* Return Number of bytes actually sent,
1340 * including headers, file, and trailers
1341 */
1342 if (ss == APR_SUCCESS)
1343 return (jlong)written;
1344 else {
1345 TCN_ERROR_WRAP(ss);
1346 return -(jlong)ss;
1347 }
1348 }
1349
1350 #else /* APR_HAS_SENDIFLE */
1351
1352 TCN_IMPLEMENT_CALL(jlong, Socket, sendfile)(TCN_STDARGS, jlong sock,
1353 jlong file,
1354 jobjectArray headers,
1355 jobjectArray trailers,
1356 jlong offset, jlong len,
1357 jint flags)
1358 {
1359
1360 UNREFERENCED_STDARGS;
1361 UNREFERENCED(sock);
1362 UNREFERENCED(file);
1363 UNREFERENCED(headers);
1364 UNREFERENCED(trailers);
1365 UNREFERENCED(offset);
1366 UNREFERENCED(len);
1367 UNREFERENCED(flags);
1368 return -(jlong)APR_ENOTIMPL;
1369 }
1370
1371 TCN_IMPLEMENT_CALL(jlong, Socket, sendfilen)(TCN_STDARGS, jlong sock,
1372 jlong file,
1373 jlong offset, jlong len,
1374 jint flags)
1375 {
1376 UNREFERENCED_STDARGS;
1377 UNREFERENCED(sock);
1378 UNREFERENCED(file);
1379 UNREFERENCED(offset);
1380 UNREFERENCED(len);
1381 UNREFERENCED(flags);
1382 return -(jlong)APR_ENOTIMPL;
1383 }
1384
1385 #endif /* APR_HAS_SENDIFLE */
1386
1387
1388 TCN_IMPLEMENT_CALL(jint, Socket, acceptfilter)(TCN_STDARGS,
1389 jlong sock,
1390 jstring name,
1391 jstring args)
1392 {
1393 #if APR_HAS_SO_ACCEPTFILTER
1394 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1395 TCN_ALLOC_CSTRING(name);
1396 TCN_ALLOC_CSTRING(args);
1397 apr_status_t rv;
1398
1399
1400 UNREFERENCED(o);
1401 rv = apr_socket_accept_filter(s->sock, J2S(name),
1402 J2S(args) ? J2S(args) : "");
1403 TCN_FREE_CSTRING(name);
1404 TCN_FREE_CSTRING(args);
1405 return (jint)rv;
1406 #else
1407 UNREFERENCED_STDARGS;
1408 UNREFERENCED(sock);
1409 UNREFERENCED(name);
1410 UNREFERENCED(args);
1411 return (jint)APR_ENOTIMPL;
1412 #endif
1413 }
1414
1415 TCN_IMPLEMENT_CALL(jint, Socket, dataSet)(TCN_STDARGS, jlong sock,
1416 jstring key, jobject data)
1417 {
1418 tcn_socket_t *s = J2P(sock, tcn_socket_t *);
1419 apr_status_t rv = APR_SUCCESS;
1420 TCN_ALLOC_CSTRING(key);
1421
1422 UNREFERENCED(o);
1423 TCN_ASSERT(sock != 0);
1424
1425 rv = apr_socket_data_set(s->sock, data, J2S(key), NULL);
1426 TCN_FREE_CSTRING(key);
1427 return rv;
1428 }
1429
1430 TCN_IMPLEMENT_CALL(jobject, Socket, dataGet)(TCN_STDARGS, jlong socket,
1431 jstring key)
1432 {
1433 tcn_socket_t *s = J2P(socket, tcn_socket_t *);
1434 TCN_ALLOC_CSTRING(key);
1435 void *rv = NULL;
1436
1437 UNREFERENCED(o);
1438 TCN_ASSERT(socket != 0);
1439
1440 if (apr_socket_data_get(&rv, J2S(key), s->sock) != APR_SUCCESS) {
1441 rv = NULL;
1442 }
1443 TCN_FREE_CSTRING(key);
1444 return rv;
1445 }
OLDNEW
« no previous file with comments | « c/native_constants.c ('k') | c/os.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698