1 /* 2 * Copyright (c) 1998, 2007, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 // 26 // Parts of the HPI interface for which the HotSparc does not use the 27 // HPI (because the interruptible IO mechanims used are different). 28 // 29 30 #include <sys/socket.h> 31 #include <sys/poll.h> 32 #include <sys/filio.h> 33 #include <unistd.h> 34 #include <netdb.h> 35 #include <setjmp.h> 36 37 // HPI_FileInterface 38 39 // Many system calls can be interrupted by signals and must be restarted. 40 // Restart support was added without disturbing the extent of thread 41 // interruption support. 42 43 inline int hpi::close(int fd) { 44 RESTARTABLE_RETURN_INT(::close(fd)); 45 } 46 47 inline size_t hpi::read(int fd, void *buf, unsigned int nBytes) { 48 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); 49 } 50 51 inline size_t hpi::write(int fd, const void *buf, unsigned int nBytes) { 52 INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted); 53 } 54 55 56 // HPI_SocketInterface 57 58 inline int hpi::socket_close(int fd) { 59 RESTARTABLE_RETURN_INT(::close(fd)); 60 } 61 62 inline int hpi::socket(int domain, int type, int protocol) { 63 return ::socket(domain, type, protocol); 64 } 65 66 inline int hpi::recv(int fd, char *buf, int nBytes, int flags) { 67 INTERRUPTIBLE_RETURN_INT(::recv(fd, buf, nBytes, flags), os::Solaris::clear_interrupted); 68 } 69 70 inline int hpi::send(int fd, char *buf, int nBytes, int flags) { 71 INTERRUPTIBLE_RETURN_INT(::send(fd, buf, nBytes, flags), os::Solaris::clear_interrupted); 72 } 73 74 inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) { 75 RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, flags)); 76 } 77 78 // As both poll and select can be interrupted by signals, we have to be 79 // prepared to restart the system call after updating the timeout, unless 80 // a poll() is done with timeout == -1, in which case we repeat with this 81 // "wait forever" value. 82 83 inline int hpi::timeout(int fd, long timeout) { 84 int res; 85 struct timeval t; 86 julong prevtime, newtime; 87 static const char* aNull = 0; 88 89 struct pollfd pfd; 90 pfd.fd = fd; 91 pfd.events = POLLIN; 92 93 gettimeofday(&t, &aNull); 94 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; 95 96 for(;;) { 97 INTERRUPTIBLE_NORESTART(::poll(&pfd, 1, timeout), res, os::Solaris::clear_interrupted); 98 if(res == OS_ERR && errno == EINTR) { 99 if(timeout != -1) { 100 gettimeofday(&t, &aNull); 101 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; 102 timeout -= newtime - prevtime; 103 if(timeout <= 0) 104 return OS_OK; 105 prevtime = newtime; 106 } 107 } else 108 return res; 109 } 110 } 111 112 inline int hpi::listen(int fd, int count) { 113 if (fd < 0) 114 return OS_ERR; 115 116 return ::listen(fd, count); 117 } 118 119 inline int 120 hpi::connect(int fd, struct sockaddr *him, int len) { 121 do { 122 int _result; 123 INTERRUPTIBLE_NORESTART(::connect(fd, him, len), _result, 124 os::Solaris::clear_interrupted); 125 126 // Depending on when thread interruption is reset, _result could be 127 // one of two values when errno == EINTR 128 129 if (((_result == OS_INTRPT) || (_result == OS_ERR)) && (errno == EINTR)) { 130 /* restarting a connect() changes its errno semantics */ 131 INTERRUPTIBLE(::connect(fd, him, len), _result, 132 os::Solaris::clear_interrupted); 133 /* undo these changes */ 134 if (_result == OS_ERR) { 135 if (errno == EALREADY) errno = EINPROGRESS; /* fall through */ 136 else if (errno == EISCONN) { errno = 0; return OS_OK; } 137 } 138 } 139 return _result; 140 } while(false); 141 } 142 143 inline int hpi::accept(int fd, struct sockaddr *him, int *len) { 144 if (fd < 0) 145 return OS_ERR; 146 INTERRUPTIBLE_RETURN_INT((int)::accept(fd, him, (socklen_t*) len), os::Solaris::clear_interrupted); 147 } 148 149 inline int hpi::recvfrom(int fd, char *buf, int nBytes, int flags, 150 sockaddr *from, int *fromlen) { 151 //%%note jvm_r11 152 INTERRUPTIBLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, (unsigned int) flags, from, (socklen_t *)fromlen), os::Solaris::clear_interrupted); 153 } 154 155 inline int hpi::sendto(int fd, char *buf, int len, int flags, 156 struct sockaddr *to, int tolen) { 157 //%%note jvm_r11 158 INTERRUPTIBLE_RETURN_INT((int)::sendto(fd, buf, len, (unsigned int) flags, to, tolen),os::Solaris::clear_interrupted); 159 } 160 161 inline int hpi::socket_available(int fd, jint *pbytes) { 162 if (fd < 0) 163 return OS_OK; 164 165 int ret; 166 167 RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); 168 169 //%% note ioctl can return 0 when successful, JVM_SocketAvailable 170 // is expected to return 0 on failure and 1 on success to the jdk. 171 172 return (ret == OS_ERR) ? 0 : 1; 173 } 174 175 176 /* 177 HPIDECL(socket_shutdown, "socket_shutdown", _socket, SocketShutdown, 178 int, "%d", 179 (int fd, int howto), 180 ("fd = %d, howto = %d", fd, howto), 181 (fd, howto)); 182 */ 183 inline int hpi::socket_shutdown(int fd, int howto){ 184 return ::shutdown(fd, howto); 185 } 186 187 /* 188 HPIDECL(bind, "bind", _socket, Bind, 189 int, "%d", 190 (int fd, struct sockaddr *him, int len), 191 ("fd = %d, him = %p, len = %d", 192 fd, him, len), 193 (fd, him, len)); 194 */ 195 inline int hpi::bind(int fd, struct sockaddr *him, int len){ 196 INTERRUPTIBLE_RETURN_INT_NORESTART(::bind(fd, him, len),os::Solaris::clear_interrupted); 197 } 198 199 /* 200 HPIDECL(get_sock_name, "get_sock_name", _socket, GetSocketName, 201 int, "%d", 202 (int fd, struct sockaddr *him, int *len), 203 ("fd = %d, him = %p, len = %p", 204 fd, him, len), 205 (fd, him, len)); 206 */ 207 inline int hpi::get_sock_name(int fd, struct sockaddr *him, int *len){ 208 return ::getsockname(fd, him, (socklen_t*) len); 209 } 210 211 /* 212 HPIDECL(get_host_name, "get_host_name", _socket, GetHostName, int, "%d", 213 (char *hostname, int namelen), 214 ("hostname = %p, namelen = %d", 215 hostname, namelen), 216 (hostname, namelen)); 217 */ 218 inline int hpi::get_host_name(char* name, int namelen){ 219 return ::gethostname(name, namelen); 220 } 221 222 /* 223 HPIDECL(get_sock_opt, "get_sock_opt", _socket, SocketGetOption, int, "%d", 224 (int fd, int level, int optname, char *optval, int* optlen), 225 ("fd = %d, level = %d, optname = %d, optval = %p, optlen = %p", 226 fd, level, optname, optval, optlen), 227 (fd, level, optname, optval, optlen)); 228 */ 229 inline int hpi::get_sock_opt(int fd, int level, int optname, 230 char *optval, int* optlen){ 231 return ::getsockopt(fd, level, optname, optval, (socklen_t*) optlen); 232 } 233 234 /* 235 HPIDECL(set_sock_opt, "set_sock_opt", _socket, SocketSetOption, int, "%d", 236 (int fd, int level, int optname, const char *optval, int optlen), 237 ("fd = %d, level = %d, optname = %d, optval = %p, optlen = %d", 238 fd, level, optname, optval, optlen), 239 (fd, level, optname, optval, optlen)); 240 */ 241 inline int hpi::set_sock_opt(int fd, int level, int optname, 242 const char *optval, int optlen){ 243 return ::setsockopt(fd, level, optname, optval, optlen); 244 } 245 246 //Reconciliation History 247 // 1.3 98/10/21 18:17:14 hpi_win32.hpp 248 // 1.6 99/06/28 11:01:36 hpi_win32.hpp 249 //End