src/aix/native/java/net/aix_close.c

Print this page
rev 8975 : 8031581: PPC64: Addons and fixes for AIX to pass the jdk regression tests


 217  *
 218  *      fd1 < 0    => close(fd2)
 219  *      fd1 >= 0   => dup2(fd1, fd2)
 220  *
 221  * Returns -1 with errno set if operation fails.
 222  */
 223 static int closefd(int fd1, int fd2) {
 224     int rv, orig_errno;
 225     fdEntry_t *fdEntry = getFdEntry(fd2);
 226     if (fdEntry == NULL) {
 227         errno = EBADF;
 228         return -1;
 229     }
 230 
 231     /*
 232      * Lock the fd to hold-off additional I/O on this fd.
 233      */
 234     pthread_mutex_lock(&(fdEntry->lock));
 235 
 236     {
 237         /*
 238          * And close/dup the file descriptor
 239          * (restart if interrupted by signal)
 240          */
 241         do {
 242             if (fd1 < 0) {
 243                 rv = close(fd2);
 244             } else {
 245                 rv = dup2(fd1, fd2);
 246             }
 247         } while (rv == -1 && errno == EINTR);
 248 
 249         /*
 250          * Send a wakeup signal to all threads blocked on this
 251          * file descriptor.
 252          */
 253         threadEntry_t *curr = fdEntry->threads;
 254         while (curr != NULL) {
 255             curr->intr = 1;
 256             pthread_kill( curr->thr, sigWakeup );

 257             curr = curr->next;
 258         }
















 259     }
 260 
 261     /*
 262      * Unlock without destroying errno
 263      */
 264     orig_errno = errno;
 265     pthread_mutex_unlock(&(fdEntry->lock));
 266     errno = orig_errno;
 267 
 268     return rv;
 269 }
 270 
 271 /*
 272  * Wrapper for dup2 - same semantics as dup2 system call except
 273  * that any threads blocked in an I/O system call on fd2 will be
 274  * preempted and return -1/EBADF;
 275  */
 276 int NET_Dup2(int fd, int fd2) {
 277     if (fd < 0) {
 278         errno = EBADF;


 296  * Macro to perform a blocking IO operation. Restarts
 297  * automatically if interrupted by signal (other than
 298  * our wakeup signal)
 299  */
 300 #define BLOCKING_IO_RETURN_INT(FD, FUNC) {      \
 301     int ret;                                    \
 302     threadEntry_t self;                         \
 303     fdEntry_t *fdEntry = getFdEntry(FD);        \
 304     if (fdEntry == NULL) {                      \
 305         errno = EBADF;                          \
 306         return -1;                              \
 307     }                                           \
 308     do {                                        \
 309         startOp(fdEntry, &self);                \
 310         ret = FUNC;                             \
 311         endOp(fdEntry, &self);                  \
 312     } while (ret == -1 && errno == EINTR);      \
 313     return ret;                                 \
 314 }
 315 












 316 int NET_Read(int s, void* buf, size_t len) {
 317     BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
 318 }
 319 
 320 int NET_ReadV(int s, const struct iovec * vector, int count) {
 321     BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
 322 }
 323 
 324 int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
 325        struct sockaddr *from, int *fromlen) {
 326     socklen_t socklen = *fromlen;
 327     BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
 328     *fromlen = socklen;
 329 }
 330 
 331 int NET_Send(int s, void *msg, int len, unsigned int flags) {
 332     BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
 333 }
 334 
 335 int NET_WriteV(int s, const struct iovec * vector, int count) {


 407 
 408         /*
 409          * If interrupted then adjust timeout. If timeout
 410          * has expired return 0 (indicating timeout expired).
 411          */
 412         if (rv < 0 && errno == EINTR) {
 413             if (timeout > 0) {
 414                 gettimeofday(&t, NULL);
 415                 newtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
 416                 timeout -= newtime - prevtime;
 417                 if (timeout <= 0) {
 418                     return 0;
 419                 }
 420                 prevtime = newtime;
 421             }
 422         } else {
 423             return rv;
 424         }
 425 
 426     }


































 427 }


 217  *
 218  *      fd1 < 0    => close(fd2)
 219  *      fd1 >= 0   => dup2(fd1, fd2)
 220  *
 221  * Returns -1 with errno set if operation fails.
 222  */
 223 static int closefd(int fd1, int fd2) {
 224     int rv, orig_errno;
 225     fdEntry_t *fdEntry = getFdEntry(fd2);
 226     if (fdEntry == NULL) {
 227         errno = EBADF;
 228         return -1;
 229     }
 230 
 231     /*
 232      * Lock the fd to hold-off additional I/O on this fd.
 233      */
 234     pthread_mutex_lock(&(fdEntry->lock));
 235 
 236     {
 237         /* On fast machines we see that we enter dup2 before the
 238          * accepting thread had a chance to get and process the signal.
 239          * So in case we woke a thread up, give it some time to cope.
 240          * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */
 241         int num_woken = 0;






 242 
 243         /*
 244          * Send a wakeup signal to all threads blocked on this
 245          * file descriptor.
 246          */
 247         threadEntry_t *curr = fdEntry->threads;
 248         while (curr != NULL) {
 249             curr->intr = 1;
 250             pthread_kill( curr->thr, sigWakeup );
 251             num_woken ++;
 252             curr = curr->next;
 253         }
 254 
 255         if (num_woken > 0) {
 256           usleep(num_woken * 50);
 257         }
 258 
 259         /*
 260          * And close/dup the file descriptor
 261          * (restart if interrupted by signal)
 262          */
 263         do {
 264             if (fd1 < 0) {
 265                 rv = close(fd2);
 266             } else {
 267                 rv = dup2(fd1, fd2);
 268             }
 269         } while (rv == -1 && errno == EINTR);
 270     }
 271 
 272     /*
 273      * Unlock without destroying errno
 274      */
 275     orig_errno = errno;
 276     pthread_mutex_unlock(&(fdEntry->lock));
 277     errno = orig_errno;
 278 
 279     return rv;
 280 }
 281 
 282 /*
 283  * Wrapper for dup2 - same semantics as dup2 system call except
 284  * that any threads blocked in an I/O system call on fd2 will be
 285  * preempted and return -1/EBADF;
 286  */
 287 int NET_Dup2(int fd, int fd2) {
 288     if (fd < 0) {
 289         errno = EBADF;


 307  * Macro to perform a blocking IO operation. Restarts
 308  * automatically if interrupted by signal (other than
 309  * our wakeup signal)
 310  */
 311 #define BLOCKING_IO_RETURN_INT(FD, FUNC) {      \
 312     int ret;                                    \
 313     threadEntry_t self;                         \
 314     fdEntry_t *fdEntry = getFdEntry(FD);        \
 315     if (fdEntry == NULL) {                      \
 316         errno = EBADF;                          \
 317         return -1;                              \
 318     }                                           \
 319     do {                                        \
 320         startOp(fdEntry, &self);                \
 321         ret = FUNC;                             \
 322         endOp(fdEntry, &self);                  \
 323     } while (ret == -1 && errno == EINTR);      \
 324     return ret;                                 \
 325 }
 326 
 327 int IO_Fcntl(int s, int cmd, void *arg) {
 328     BLOCKING_IO_RETURN_INT( s, fcntl(s, cmd, arg) );
 329 }
 330 
 331 int IO_Write(int s, void* buf, size_t len) {
 332     BLOCKING_IO_RETURN_INT( s, write(s, buf, len) );
 333 }
 334 
 335 int IO_Read(int s, void* buf, size_t len) {
 336     BLOCKING_IO_RETURN_INT( s, read(s, buf, len) );
 337 }
 338 
 339 int NET_Read(int s, void* buf, size_t len) {
 340     BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
 341 }
 342 
 343 int NET_ReadV(int s, const struct iovec * vector, int count) {
 344     BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
 345 }
 346 
 347 int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
 348        struct sockaddr *from, int *fromlen) {
 349     socklen_t socklen = *fromlen;
 350     BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
 351     *fromlen = socklen;
 352 }
 353 
 354 int NET_Send(int s, void *msg, int len, unsigned int flags) {
 355     BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
 356 }
 357 
 358 int NET_WriteV(int s, const struct iovec * vector, int count) {


 430 
 431         /*
 432          * If interrupted then adjust timeout. If timeout
 433          * has expired return 0 (indicating timeout expired).
 434          */
 435         if (rv < 0 && errno == EINTR) {
 436             if (timeout > 0) {
 437                 gettimeofday(&t, NULL);
 438                 newtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
 439                 timeout -= newtime - prevtime;
 440                 if (timeout <= 0) {
 441                     return 0;
 442                 }
 443                 prevtime = newtime;
 444             }
 445         } else {
 446             return rv;
 447         }
 448 
 449     }
 450 }
 451 
 452 /* hard coded values in java code do not match system header values */
 453 #define JAVA_POLLIN        0x0001
 454 #define JAVA_POLLOUT       0x0004
 455 #define JAVA_POLLERR       0x0008
 456 #define JAVA_POLLHUP       0x0010
 457 #define JAVA_POLLNVAL      0x0020
 458 #define JAVA_POLLREMOVE    0x0800  /* not used yet in Java but ment to deregister fd */
 459 
 460 /* declared in src/solaris/native/java/net/net_util_md.h for AIX only */
 461 int javaToNativeEvents(int javaEvents) {
 462     int nativeEvents = 0;
 463     if (javaEvents & JAVA_POLLIN)     nativeEvents |= POLLIN;
 464     if (javaEvents & JAVA_POLLOUT)    nativeEvents |= POLLOUT;
 465     if (javaEvents & JAVA_POLLERR)    nativeEvents |= POLLERR;
 466     if (javaEvents & JAVA_POLLHUP)    nativeEvents |= POLLHUP;
 467     if (javaEvents & JAVA_POLLNVAL)   nativeEvents |= POLLNVAL;
 468     if (javaEvents & JAVA_POLLREMOVE) {
 469         /* For the time being we don't support JAVA_POLLREMOVE on AIX. Just check. */
 470         fprintf(stderr, "POLLREMOVE not supported on AIX");
 471     }
 472     return nativeEvents;
 473 }
 474 
 475 /* declared in src/solaris/native/java/net/net_util_md.h for AIX only */
 476 int nativeToJavaEvents(int nativeEvents) {
 477     int javaEvents = 0;
 478     if (nativeEvents & POLLIN)   javaEvents |= JAVA_POLLIN;
 479     if (nativeEvents & POLLOUT)  javaEvents |= JAVA_POLLOUT;
 480     if (nativeEvents & POLLERR)  javaEvents |= JAVA_POLLERR;
 481     if (nativeEvents & POLLHUP)  javaEvents |= JAVA_POLLHUP;
 482     if (nativeEvents & POLLNVAL) javaEvents |= JAVA_POLLNVAL;
 483     return javaEvents;
 484 }