Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/demo/jni/Poller/Poller.c
32287 views
1
/*
2
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
/*
42
**********************************************************************
43
* Poller.c :
44
* JNI code for use with Poller.java, principally to take advantage
45
* of poll() or /dev/poll multiplexing.
46
*
47
* One will need Solaris 8 or Solaris 7 with adequate patches to take
48
* advantage of the /dev/poll performance enhancements, though any
49
* version of Solaris 7 will automatically use the kernel poll()
50
* caching. And poll() will function in 2.5.1 and 2.6 as well, but
51
* will not perform well for large numbers of file descriptors.
52
*
53
* Several assumptions have been made to simplify this code :
54
* 1> At most MAX_HANDLES (32) separate pollable entities are currently
55
* supported.
56
* 2> Global synchronization from Java is assumed for all init, create
57
* and destroy routines. Per Object (handle passed in) synchronization
58
* is required for all AddFd, RemoveFd, IsMember, and Wait routines.
59
* 3> It is currently up to the user to handle waking up an
60
* existing nativeWait() call to do an addfd or removefd on
61
* that set...could implement that here with an extra pipe, or
62
* with a pair of loopback sockets in Poller.java or user code.
63
* In most cases interruption is not necessary for deletions,
64
* so long as deletions are queued up outside the Poller class
65
* and then executed the next time waitMultiple() returns.
66
* 4> /dev/poll performance could be slightly improved by coalescing
67
* adds/removes so that a write() is only done before the ioctl
68
* (DP_POLL), but this complicates exception handling and sees
69
* only modest performance gains so wasn't done.
70
* 5> /dev/poll does not report errors on attempts to remove non-
71
* extant fds, but a future bug fix to the /dev/poll device driver
72
* should solve this problem.
73
* 6> Could add simpler code for pre-Solaris 7 releases which will
74
* perform slightly better on those OSs. But again there
75
* are only modest gains to be had from these new code paths,
76
* so they've been omitted here.
77
*
78
* Compile "cc -G -o <dest_dir>/libpoller.so -I ${JAVA_HOME}/include " \
79
* -I ${JAVA_HOME}/include/solaris Poller.c" and place the <dest_dir>
80
* in your LD_LIBRARY_PATH
81
*
82
**********************************************************************
83
*/
84
85
#include <stdio.h>
86
#include <unistd.h>
87
#include <errno.h>
88
#include <poll.h>
89
#include <malloc.h>
90
#include <fcntl.h>
91
92
93
/*
94
* Remove "_NOT"s to turn on features
95
* Append "_NOT" to turn off features.
96
* Use of /dev/poll requires both the include file and kernel driver.
97
*/
98
#define DEBUG_NOT
99
#define DEVPOLL_NOT
100
101
#ifdef DEVPOLL
102
#include <sys/devpoll.h>
103
#endif
104
105
#include "Poller.h"
106
107
#define MAX_HANDLES 32
108
109
110
#ifdef DEBUG
111
#define DBGMSG(x) printf x
112
#define ASSERT(x) {if (!(x)) \
113
printf("assertion(%s) failed at line : %d\n",#x,__LINE__);}
114
#define CHECK_HANDLE(x) check_handle(x)
115
#else
116
#define DBGMSG(x)
117
#define ASSERT(x)
118
#define CHECK_HANDLE(x)
119
#endif
120
121
/*
122
* Globals ...protect all with a global synchronization object.
123
*/
124
125
static int Current_handle = 0;
126
static int Use_devpoll = 0;
127
static int Max_index = 0;
128
129
/*
130
* Per Poller object data.
131
* Must be synchronized on a per Poller object basis.
132
*/
133
134
typedef struct ioevent {
135
int inuse;
136
int devpollfd;
137
int last_index;
138
int total_free;
139
int left_events;
140
int max_index;
141
pollfd_t *pfd;
142
} ioevent_t;
143
144
static ioevent_t IOE_handles[MAX_HANDLES];
145
146
/*
147
* Exceptions to be thrown.
148
* Note : assuming all illegal argument and NULL pointer checks
149
* have already been done by the Java calling methods.
150
*/
151
static jint throwOutOfMemoryError(JNIEnv *env, const char * cause)
152
{
153
(*env)->ThrowNew(env, (*env)->FindClass(env,"java/lang/OutOfMemoryError"),
154
cause);
155
return -1;
156
}
157
static jint throwInterruptedIOException(JNIEnv *env, const char * cause)
158
{
159
(*env)->ThrowNew(env,
160
(*env)->FindClass(env,"java/io/InterruptedIOException"),
161
cause);
162
return -1;
163
}
164
static jint throwIllegalStateException(JNIEnv *env, const char * cause)
165
{
166
(*env)->ThrowNew(env,
167
(*env)->FindClass(env,"java/lang/IllegalStateException"),
168
cause);
169
return -1;
170
}
171
172
#define MEMORY_EXCEPTION(str) throwOutOfMemoryError(env, "Poller:" str)
173
#define STATE_EXCEPTION(str) throwIllegalStateException(env, "Poller:" str)
174
#define INTERRUPT_EXCEPTION(str) throwInterruptedIOException(env, \
175
"Poller:" str)
176
jint addfd(JNIEnv *, ioevent_t *, jint, jshort);
177
jint removefd(JNIEnv *, ioevent_t *, jint);
178
179
/*
180
* Class Poller
181
* Method: nativeInit
182
* Signature: ()I
183
*
184
* Only to be called once, right after this library is loaded,
185
* so no need to deal with reentrancy here.
186
* Could do as a pragma ini, but that isn't as portable.
187
*/
188
JNIEXPORT jint JNICALL Java_Poller_nativeInit(JNIEnv *env, jclass cls)
189
{
190
int testdevpollfd;
191
int i;
192
193
#ifdef DEVPOLL
194
/*
195
* See if we can use this much faster method
196
* Note : must have fix for BUGID # 4223353 or OS can crash!
197
*/
198
testdevpollfd = open("/dev/poll",O_RDWR);
199
if (testdevpollfd >= 0) {
200
/*
201
* If Solaris 7, we need a patch
202
* Until we know what string to search for, we'll play it
203
* safe and disable this for Solaris 7.
204
*/
205
206
if (!strcmp(name.release,"5.7"))
207
{
208
Use_devpoll = 0;
209
}
210
else
211
{
212
Use_devpoll = 1;
213
}
214
}
215
216
DBGMSG(("Use_devpoll=%d\n" ,Use_devpoll));
217
close(testdevpollfd);
218
#endif
219
220
/*
221
* For now, we optimize for Solaris 7 if /dev/poll isn't
222
* available, as it is only a small % hit for Solaris < 7.
223
* if ( (Use_devpoll == 0) && !strcmp(name.release,"5.6") )
224
* Use_sol7opt = 0;
225
*/
226
Current_handle = 0;
227
for (i = 0; i < MAX_HANDLES; i++) {
228
IOE_handles[i].devpollfd = -1;
229
IOE_handles[i].pfd = NULL;
230
}
231
232
/*
233
* this tells me the max number of open filedescriptors
234
*/
235
Max_index = sysconf(_SC_OPEN_MAX);
236
if (Max_index < 0) {
237
Max_index = 1024;
238
}
239
240
DBGMSG(("got sysconf(_SC_OPEN_MAX)=%d file desc\n",Max_index));
241
242
return 0;
243
}
244
245
JNIEXPORT jint JNICALL Java_Poller_getNumCPUs(JNIEnv *env, jclass cls)
246
{
247
return sysconf(_SC_NPROCESSORS_ONLN);
248
}
249
250
/*
251
* Class: Poller
252
* Method: nativeCreatePoller
253
* Signature: (I)I
254
* Note : in the case where /dev/poll doesn't exist,
255
* using more than one poll array could hurt
256
* Solaris 7 performance due to kernel caching.
257
*/
258
259
JNIEXPORT jint JNICALL Java_Poller_nativeCreatePoller
260
(JNIEnv *env, jobject obj, jint maximum_fds)
261
{
262
int handle, retval, i;
263
ioevent_t *ioeh;
264
265
if (maximum_fds == -1) {
266
maximum_fds = Max_index;
267
}
268
handle = Current_handle;
269
if (Current_handle >= MAX_HANDLES) {
270
for (i = 0; i < MAX_HANDLES; i++) {
271
if (IOE_handles[i].inuse == 0) {
272
handle = i;
273
break;
274
}
275
}
276
if (handle >= MAX_HANDLES) {
277
return MEMORY_EXCEPTION("CreatePoller - MAX_HANDLES exceeded");
278
}
279
} else {
280
Current_handle++;
281
}
282
283
ioeh = &IOE_handles[handle];
284
285
ioeh->inuse = 1;
286
287
ioeh->last_index = 0;
288
ioeh->total_free = 0;
289
ioeh->left_events = 0;
290
ioeh->max_index = maximum_fds;
291
292
retval = handle;
293
if (Use_devpoll) {
294
ioeh->devpollfd = open("/dev/poll",O_RDWR);
295
DBGMSG(("Opened /dev/poll, set devpollfd = %d\n",ioeh->devpollfd));
296
if (ioeh->devpollfd < 0) {
297
Current_handle--;
298
return MEMORY_EXCEPTION("CreatePoller - can\'t open /dev/poll");
299
}
300
}
301
ioeh->pfd = malloc(maximum_fds * sizeof(pollfd_t));
302
if (ioeh->pfd == NULL) {
303
Current_handle--;
304
return MEMORY_EXCEPTION("CreatePoller - malloc failure");
305
}
306
307
return retval;
308
}
309
310
/*
311
* Class: Poller
312
* Method: nativeDestroyPoller
313
* Signature: (I)V
314
*/
315
JNIEXPORT void JNICALL Java_Poller_nativeDestroyPoller
316
(JNIEnv *env, jobject obj, jint handle)
317
{
318
319
ioevent_t *ioeh;
320
321
if (handle < 0 || handle >= MAX_HANDLES)
322
{
323
STATE_EXCEPTION("DestroyPoller - handle out of range");
324
return;
325
}
326
327
ioeh = &IOE_handles[handle];
328
ioeh->inuse = 0;
329
if (Use_devpoll) {
330
close(ioeh->devpollfd);
331
}
332
free(ioeh->pfd);
333
}
334
335
#ifdef DEBUG
336
static void check_handle(ioevent_t *ioeh)
337
{
338
int i,used,unused;
339
340
used=unused=0;
341
for (i = 0; i < ioeh->last_index; i++)
342
{
343
if (ioeh->pfd[i].fd == -1)
344
unused++;
345
else
346
used++;
347
}
348
if (unused != ioeh->total_free)
349
printf("WARNING : found %d free, claimed %d. Used : %d\n",
350
unused, ioeh->total_free, used);
351
}
352
#endif
353
354
/*
355
* Class: Poller
356
* Method: nativeAddFd
357
* Signature: (IIS)I
358
*
359
* Currently doesn't check to make sure we aren't adding
360
* an fd already added (no problem for /dev/poll...just
361
* an array waster for poll()).
362
*/
363
JNIEXPORT jint JNICALL Java_Poller_nativeAddFd
364
(JNIEnv *env, jobject obj, jint handle, jint fd, jshort events)
365
{
366
int retval;
367
ioevent_t *ioeh;
368
369
if (handle < 0 || handle >= MAX_HANDLES)
370
return STATE_EXCEPTION("AddFd - handle out of range");
371
372
ioeh = &IOE_handles[handle];
373
374
CHECK_HANDLE(ioeh);
375
376
#ifdef DEVPOLL
377
if (Use_devpoll)
378
{
379
int i;
380
pollfd_t pollelt;
381
382
/*
383
* use /dev/poll
384
*/
385
pollelt.fd = fd;
386
pollelt.events = events;
387
if ((i = write(ioeh->devpollfd, &pollelt, sizeof(pollfd_t))) !=
388
sizeof(pollfd_t)) {
389
DBGMSG(("write to devpollfd=%d showed %d bytes out of %d\n",
390
ioeh->devpollfd,i,sizeof(pollfd_t)));
391
return STATE_EXCEPTION("AddFd - /dev/poll add failure");
392
}
393
else
394
{
395
retval = fd;
396
}
397
}
398
else
399
#endif
400
{ /* no /dev/poll available */
401
retval = addfd(env, ioeh, fd, events);
402
}
403
return retval;
404
}
405
406
/*
407
* Addfd to pollfd array...optimized for Solaris 7
408
*/
409
jint addfd(JNIEnv *env, ioevent_t *ioeh, jint fd, jshort events)
410
{
411
int idx;
412
413
if (ioeh->total_free)
414
{
415
/*
416
* Traversing from end because that's where we pad.
417
*/
418
ioeh->total_free--;
419
for (idx = ioeh->last_index - 1; idx >= 0; idx--) {
420
if (ioeh->pfd[idx].fd == -1)
421
break;
422
}
423
}
424
else if (ioeh->last_index >= ioeh->max_index)
425
{
426
return MEMORY_EXCEPTION("AddFd - too many fds");
427
}
428
else
429
{
430
int i;
431
int new_total;
432
/*
433
* For Solaris 7, want to add some growth space
434
* and fill extras with fd=-1. This allows for
435
* kernel poll() implementation to perform optimally.
436
*/
437
new_total = ioeh->last_index;
438
new_total += (new_total/10) + 1; /* bump size by 10% */
439
if (new_total > ioeh->max_index)
440
new_total = ioeh->max_index;
441
for (i = ioeh->last_index; i <= new_total; i++)
442
{
443
ioeh->pfd[i].fd = -1;
444
}
445
idx = ioeh->last_index;
446
ioeh->total_free = new_total - ioeh->last_index - 1;
447
DBGMSG(("Just grew from %d to %d in size\n",
448
ioeh->last_index, new_total));
449
ioeh->last_index = new_total;
450
}
451
ASSERT((idx >= 0) && (idx <= ioeh->max_index));
452
ASSERT(ioeh->pfd[idx].fd == -1);
453
ioeh->pfd[idx].fd = fd;
454
ioeh->pfd[idx].events = events;
455
ioeh->pfd[idx].revents = 0;
456
457
CHECK_HANDLE(ioeh);
458
459
return fd;
460
}
461
462
/*
463
* Class: Poller
464
* Method: nativeRemoveFd
465
* Signature: (II)I
466
*/
467
JNIEXPORT jint JNICALL Java_Poller_nativeRemoveFd
468
(JNIEnv *env, jobject obj, jint handle, jint fd)
469
{
470
ioevent_t *ioeh;
471
472
if (handle < 0 || handle >= MAX_HANDLES)
473
return STATE_EXCEPTION("RemoveFd - handle out of range");
474
475
ioeh = &IOE_handles[handle];
476
477
#ifdef DEVPOLL
478
if (Use_devpoll)
479
{
480
/*
481
* use /dev/poll - currently no need for locking here.
482
*/
483
pollfd_t pollelt;
484
485
pollelt.fd = fd;
486
pollelt.events = POLLREMOVE;
487
if (write(ioeh->devpollfd, &pollelt,
488
sizeof(pollfd_t) ) != sizeof(pollfd_t))
489
{
490
return STATE_EXCEPTION("RemoveFd - /dev/poll failure");
491
}
492
}
493
else
494
#endif DEVPOLL
495
{
496
return removefd(env, ioeh,fd);
497
}
498
}
499
/*
500
* remove from pollfd array...optimize for Solaris 7
501
*/
502
jint removefd(JNIEnv *env, ioevent_t *ioeh, jint fd)
503
{
504
int i;
505
int found = 0;
506
507
{ /* !Use_devpoll */
508
for (i = 0; i < ioeh->last_index; i++)
509
{
510
if (ioeh->pfd[i].fd == fd)
511
{
512
ioeh->pfd[i].fd = -1;
513
found = 1;
514
break;
515
}
516
}
517
if (!found)
518
{
519
return STATE_EXCEPTION("RemoveFd - no such fd");
520
}
521
ioeh->left_events = 0; /* Have to go back to the kernel */
522
ioeh->total_free++;
523
/*
524
* Shrinking pool if > 33% empty. Just don't do this often!
525
*/
526
if ( (ioeh->last_index > 100) &&
527
(ioeh->total_free > (ioeh->last_index / 3)) )
528
{
529
int j;
530
/*
531
* we'll just bite the bullet here, since we're > 33% empty.
532
* walk through and eliminate -1 fd values, shrink total
533
* size to still have ~ 10 fd==-1 values at end.
534
* Start at end (since we pad here) and, when we find fd != -1,
535
* swap with an earlier fd == -1 until we have all -1 values
536
* at the end.
537
*/
538
CHECK_HANDLE(ioeh);
539
for (i = ioeh->last_index - 1, j = 0; i > j; i--)
540
{
541
if (ioeh->pfd[i].fd != -1)
542
{
543
while ( (j < i) && (ioeh->pfd[j].fd != -1) )
544
j++;
545
DBGMSG( ("i=%d,j=%d,ioeh->pfd[j].fd=%d\n",
546
i, j, ioeh->pfd[j].fd) );
547
if (j < i)
548
{
549
ASSERT(ioeh->pfd[j].fd == -1);
550
ioeh->pfd[j].fd = ioeh->pfd[i].fd;
551
ioeh->pfd[j].events = ioeh->pfd[i].events;
552
ioeh->pfd[i].fd = -1;
553
}
554
}
555
}
556
DBGMSG(("Just shrunk from %d to %d in size\n",
557
ioeh->last_index, j+11));
558
ioeh->last_index = j + 11; /* last_index always 1 greater */
559
ioeh->total_free = 10;
560
CHECK_HANDLE(ioeh);
561
}
562
} /* !Use_devpoll */
563
564
return 1;
565
}
566
567
/*
568
* Class: Poller
569
* Method: nativeIsMember
570
* Signature: (II)I
571
*/
572
JNIEXPORT jint JNICALL Java_Poller_nativeIsMember
573
(JNIEnv *env, jobject obj, jint handle, jint fd)
574
{
575
int found = 0;
576
int i;
577
ioevent_t *ioeh;
578
579
if (handle < 0 || handle >= MAX_HANDLES)
580
return STATE_EXCEPTION("IsMember - handle out of range");
581
582
ioeh = &IOE_handles[handle];
583
584
#ifdef DEVPOLL
585
if (Use_devpoll)
586
{
587
pollfd_t pfd;
588
/*
589
* DEVPOLL ioctl DP_ISPOLLED call to determine if fd is polled.
590
*/
591
pfd.fd = fd;
592
pfd.events = 0;
593
pfd.revents = 0;
594
found = ioctl(ioeh->devpollfd, DP_ISPOLLED, &pfd);
595
if (found == -1)
596
{
597
return STATE_EXCEPTION("IsMember - /dev/poll failure");
598
}
599
}
600
else
601
#endif
602
{
603
for (i = 0; i < ioeh->last_index; i++)
604
{
605
if (fd == ioeh->pfd[i].fd)
606
{
607
found = 1;
608
break;
609
}
610
}
611
}
612
613
return found;
614
}
615
616
/*
617
* Class: Poller
618
* Method: nativeWait
619
* Signature: (II[I[SJ)I
620
*/
621
JNIEXPORT jint JNICALL Java_Poller_nativeWait
622
(JNIEnv *env, jobject obj, jint handle, jint maxEvents,
623
jintArray jfds, jshortArray jrevents, jlong timeout)
624
{
625
int useEvents, count, idx;
626
short *reventp;
627
jint *fdp;
628
int retval;
629
ioevent_t *ioeh;
630
jboolean isCopy1,isCopy2;
631
632
if (handle < 0 || handle >= MAX_HANDLES)
633
return STATE_EXCEPTION("nativeWait - handle out of range");
634
635
ioeh = &IOE_handles[handle];
636
637
if (maxEvents == 0) /* just doing a kernel delay! */
638
{
639
useEvents = poll(NULL,0L,timeout);
640
return 0;
641
}
642
643
#ifdef DEVPOLL
644
if (Use_devpoll)
645
{
646
struct dvpoll dopoll;
647
/*
648
* DEVPOLL ioctl DP_POLL call, reading
649
*/
650
dopoll.dp_timeout = timeout;
651
dopoll.dp_nfds=maxEvents;
652
dopoll.dp_fds=ioeh->pfd;
653
654
useEvents = ioctl(ioeh->devpollfd, DP_POLL, &dopoll);
655
while ((useEvents == -1) && (errno == EAGAIN))
656
useEvents = ioctl(ioeh->devpollfd, DP_POLL, &dopoll);
657
658
if (useEvents == -1)
659
{
660
if (errno == EINTR)
661
return INTERRUPT_EXCEPTION("nativeWait - /dev/poll failure EINTR");
662
else
663
return STATE_EXCEPTION("nativeWait - /dev/poll failure");
664
}
665
666
reventp =(*env)->GetShortArrayElements(env,jrevents,&isCopy1);
667
fdp =(*env)->GetIntArrayElements(env,jfds,&isCopy2);
668
for (idx = 0,count = 0; idx < useEvents; idx++)
669
{
670
if (ioeh->pfd[idx].revents)
671
{
672
fdp[count] = ioeh->pfd[idx].fd;
673
reventp[count] = ioeh->pfd[idx].revents;
674
count++;
675
}
676
}
677
if (count < useEvents)
678
return STATE_EXCEPTION("Wait - Corrupted internals");
679
680
if (isCopy1 == JNI_TRUE)
681
(*env)->ReleaseShortArrayElements(env,jrevents,reventp,0);
682
if (isCopy2 == JNI_TRUE)
683
(*env)->ReleaseIntArrayElements(env,jfds,fdp,0);
684
}
685
else
686
#endif
687
{ /* !Use_devpoll */
688
689
/* no leftovers=>go to kernel */
690
if (ioeh->left_events == 0)
691
{
692
useEvents = poll(ioeh->pfd,ioeh->last_index, timeout);
693
while ((useEvents == -1) && (errno == EAGAIN))
694
useEvents = poll(ioeh->pfd,ioeh->last_index, timeout);
695
if (useEvents == -1)
696
{
697
if (errno == EINTR)
698
return INTERRUPT_EXCEPTION("Wait - poll() failure EINTR-" \
699
"IO interrupted.");
700
else if (errno == EINVAL)
701
return STATE_EXCEPTION("Wait - poll() failure EINVAL-" \
702
"invalid args (is fdlim cur < max?)");
703
else
704
return STATE_EXCEPTION("Wait - poll() failure");
705
}
706
ioeh->left_events = useEvents;
707
DBGMSG(("waitnative : poll returns : %d\n",useEvents));
708
}
709
else
710
{ /* left over from last call */
711
useEvents = ioeh->left_events;
712
}
713
714
if (useEvents > maxEvents)
715
{
716
useEvents = maxEvents;
717
}
718
719
ioeh->left_events -= useEvents; /* left to process */
720
721
DBGMSG(("waitnative : left %d, use %d, max %d\n",ioeh->left_events,
722
useEvents,maxEvents));
723
724
if (useEvents > 0)
725
{
726
reventp =(*env)->GetShortArrayElements(env,jrevents,&isCopy1);
727
fdp =(*env)->GetIntArrayElements(env,jfds,&isCopy2);
728
for (idx = 0,count = 0; (idx < ioeh->last_index) &&
729
(count < useEvents); idx++)
730
{
731
if (ioeh->pfd[idx].revents)
732
{
733
fdp[count] = ioeh->pfd[idx].fd;
734
reventp[count] = ioeh->pfd[idx].revents;
735
/* in case of leftover for next walk */
736
ioeh->pfd[idx].revents = 0;
737
count++;
738
}
739
}
740
if (count < useEvents)
741
{
742
ioeh->left_events = 0;
743
return STATE_EXCEPTION("Wait - Corrupted internals");
744
}
745
if (isCopy1 == JNI_TRUE)
746
(*env)->ReleaseShortArrayElements(env,jrevents,reventp,0);
747
if (isCopy2 == JNI_TRUE)
748
(*env)->ReleaseIntArrayElements(env,jfds,fdp,0);
749
}
750
} /* !Use_devpoll */
751
752
return useEvents;
753
}
754
755