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/native/sun/nio/ch/DevPollArrayWrapper.c
32288 views
1
/*
2
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "jni.h"
27
#include "jni_util.h"
28
#include "jvm.h"
29
#include "jlong.h"
30
#include "sun_nio_ch_DevPollArrayWrapper.h"
31
#include <sys/poll.h>
32
#include <unistd.h>
33
#include <sys/time.h>
34
35
#ifdef __cplusplus
36
extern "C" {
37
#endif
38
39
typedef uint32_t caddr32_t;
40
41
/* /dev/poll ioctl */
42
#define DPIOC (0xD0 << 8)
43
#define DP_POLL (DPIOC | 1) /* poll on fds in cached in /dev/poll */
44
#define DP_ISPOLLED (DPIOC | 2) /* is this fd cached in /dev/poll */
45
#define DEVPOLLSIZE 1000 /* /dev/poll table size increment */
46
#define POLLREMOVE 0x0800 /* Removes fd from monitored set */
47
48
/*
49
* /dev/poll DP_POLL ioctl format
50
*/
51
typedef struct dvpoll {
52
pollfd_t *dp_fds; /* pollfd array */
53
nfds_t dp_nfds; /* num of pollfd's in dp_fds[] */
54
int dp_timeout; /* time out in millisec */
55
} dvpoll_t;
56
57
typedef struct dvpoll32 {
58
caddr32_t dp_fds; /* pollfd array */
59
uint32_t dp_nfds; /* num of pollfd's in dp_fds[] */
60
int32_t dp_timeout; /* time out in millisec */
61
} dvpoll32_t;
62
63
#ifdef __cplusplus
64
}
65
#endif
66
67
#define RESTARTABLE(_cmd, _result) do { \
68
do { \
69
_result = _cmd; \
70
} while((_result == -1) && (errno == EINTR)); \
71
} while(0)
72
73
static int
74
idevpoll(jint wfd, int dpctl, struct dvpoll a)
75
{
76
jlong start, now;
77
int remaining = a.dp_timeout;
78
struct timeval t;
79
int diff;
80
81
gettimeofday(&t, NULL);
82
start = t.tv_sec * 1000 + t.tv_usec / 1000;
83
84
for (;;) {
85
/* poll(7d) ioctl does not return remaining count */
86
int res = ioctl(wfd, dpctl, &a);
87
if (res < 0 && errno == EINTR) {
88
if (remaining >= 0) {
89
gettimeofday(&t, NULL);
90
now = t.tv_sec * 1000 + t.tv_usec / 1000;
91
diff = now - start;
92
remaining -= diff;
93
if (diff < 0 || remaining <= 0) {
94
return 0;
95
}
96
start = now;
97
a.dp_timeout = remaining;
98
}
99
} else {
100
return res;
101
}
102
}
103
}
104
105
JNIEXPORT jint JNICALL
106
Java_sun_nio_ch_DevPollArrayWrapper_init(JNIEnv *env, jobject this)
107
{
108
int wfd = open("/dev/poll", O_RDWR);
109
if (wfd < 0) {
110
JNU_ThrowIOExceptionWithLastError(env, "Error opening driver");
111
return -1;
112
}
113
return wfd;
114
}
115
116
JNIEXPORT void JNICALL
117
Java_sun_nio_ch_DevPollArrayWrapper_register(JNIEnv *env, jobject this,
118
jint wfd, jint fd, jint mask)
119
{
120
struct pollfd a[1];
121
int n;
122
123
a[0].fd = fd;
124
a[0].events = mask;
125
a[0].revents = 0;
126
127
n = write(wfd, &a[0], sizeof(a));
128
if (n != sizeof(a)) {
129
if (n < 0) {
130
JNU_ThrowIOExceptionWithLastError(env, "Error writing pollfds");
131
} else {
132
JNU_ThrowIOException(env, "Unexpected number of bytes written");
133
}
134
}
135
}
136
137
JNIEXPORT void JNICALL
138
Java_sun_nio_ch_DevPollArrayWrapper_registerMultiple(JNIEnv *env, jobject this,
139
jint wfd, jlong address,
140
jint len)
141
{
142
unsigned char *pollBytes = (unsigned char *)jlong_to_ptr(address);
143
unsigned char *pollEnd = pollBytes + sizeof(struct pollfd) * len;
144
while (pollBytes < pollEnd) {
145
int bytesWritten = write(wfd, pollBytes, (int)(pollEnd - pollBytes));
146
if (bytesWritten < 0) {
147
JNU_ThrowIOExceptionWithLastError(env, "Error writing pollfds");
148
return;
149
}
150
pollBytes += bytesWritten;
151
}
152
}
153
154
JNIEXPORT jint JNICALL
155
Java_sun_nio_ch_DevPollArrayWrapper_poll0(JNIEnv *env, jobject this,
156
jlong address, jint numfds,
157
jlong timeout, jint wfd)
158
{
159
struct dvpoll a;
160
void *pfd = (void *) jlong_to_ptr(address);
161
int result = 0;
162
163
a.dp_fds = pfd;
164
a.dp_nfds = numfds;
165
a.dp_timeout = (int)timeout;
166
167
if (timeout <= 0) { /* Indefinite or no wait */
168
RESTARTABLE (ioctl(wfd, DP_POLL, &a), result);
169
} else { /* Bounded wait; bounded restarts */
170
result = idevpoll(wfd, DP_POLL, a);
171
}
172
173
if (result < 0) {
174
JNU_ThrowIOExceptionWithLastError(env, "Error reading driver");
175
return -1;
176
}
177
return result;
178
}
179
180
JNIEXPORT void JNICALL
181
Java_sun_nio_ch_DevPollArrayWrapper_interrupt(JNIEnv *env, jclass this, jint fd)
182
{
183
int fakebuf[1];
184
fakebuf[0] = 1;
185
if (write(fd, fakebuf, 1) < 0) {
186
JNU_ThrowIOExceptionWithLastError(env,
187
"Write to interrupt fd failed");
188
}
189
}
190
191