src/solaris/native/java/net/bsd_close.c

Print this page




   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 <stdio.h>
  27 #include <stdlib.h>

  28 #include <signal.h>
  29 #include <pthread.h>
  30 #include <sys/types.h>
  31 #include <sys/socket.h>
  32 #include <sys/select.h>
  33 #include <sys/time.h>
  34 #include <sys/resource.h>
  35 #include <sys/uio.h>
  36 #include <unistd.h>
  37 #include <errno.h>
  38 
  39 #include <sys/poll.h>
  40 


  41 /*
  42  * Stack allocated by thread when doing blocking operation
  43  */
  44 typedef struct threadEntry {
  45     pthread_t thr;                      /* this thread */
  46     struct threadEntry *next;           /* next thread */
  47     int intr;                           /* interrupted */
  48 } threadEntry_t;
  49 
  50 /*
  51  * Heap allocated during initialized - one entry per fd
  52  */
  53 typedef struct {
  54     pthread_mutex_t lock;               /* fd lock */
  55     threadEntry_t *threads;             /* threads blocked on fd */
  56 } fdEntry_t;
  57 
  58 /*
  59  * Signal to unblock thread
  60  */


 322     BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
 323 }
 324 
 325 #ifndef USE_SELECT
 326 int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
 327     BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
 328 }
 329 #else
 330 int NET_Select(int s, fd_set *readfds, fd_set *writefds,
 331                fd_set *exceptfds, struct timeval *timeout) {
 332     BLOCKING_IO_RETURN_INT( s-1,
 333                             select(s, readfds, writefds, exceptfds, timeout) );
 334 }
 335 #endif
 336 
 337 /*
 338  * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399.
 339  * Auto restarts with adjusted timeout if interrupted by
 340  * signal other than our wakeup signal.
 341  */
 342 int NET_Timeout(int s, long timeout) {
 343     long prevtime = 0, newtime;
 344     struct timeval t, *tp = &t;




 345     fdEntry_t *fdEntry = getFdEntry(s);
 346 
 347     /*
 348      * Check that fd hasn't been closed.
 349      */
 350     if (fdEntry == NULL) {
 351         errno = EBADF;
 352         return -1;
 353     }
 354 
 355     /*
 356      * Pick up current time as may need to adjust timeout
 357      */
 358     if (timeout > 0) {
 359         /* Timed */
 360         struct timeval now;
 361         gettimeofday(&now, NULL);
 362         prevtime = now.tv_sec * 1000  +  now.tv_usec / 1000;
 363         t.tv_sec = timeout / 1000;
 364         t.tv_usec = (timeout % 1000) * 1000;
 365     } else if (timeout < 0) {
 366         /* Blocking */
 367         tp = 0;
 368     } else {
 369         /* Poll */
 370         t.tv_sec = 0;
 371         t.tv_usec = 0;
 372     }
 373 














 374     for(;;) {
 375         fd_set rfds;
 376         int rv;
 377         threadEntry_t self;
 378 
 379         /*
 380          * call select on the fd. If interrupted by our wakeup signal
 381          * errno will be set to EBADF.
 382          */
 383         FD_ZERO(&rfds);
 384         FD_SET(s, &rfds);
 385 
 386         startOp(fdEntry, &self);
 387         rv = select(s+1, &rfds, 0, 0, tp);
 388         endOp(fdEntry, &self);
 389 
 390         /*
 391          * If interrupted then adjust timeout. If timeout
 392          * has expired return 0 (indicating timeout expired).
 393          */
 394         if (rv < 0 && errno == EINTR) {
 395             if (timeout > 0) {
 396                 struct timeval now;
 397                 gettimeofday(&now, NULL);
 398                 newtime = now.tv_sec * 1000  +  now.tv_usec / 1000;
 399                 timeout -= newtime - prevtime;
 400                 if (timeout <= 0) {


 401                     return 0;
 402                 }
 403                 prevtime = newtime;
 404                 t.tv_sec = timeout / 1000;
 405                 t.tv_usec = (timeout % 1000) * 1000;
 406             }
 407         } else {


 408             return rv;
 409         }
 410 
 411     }
 412 }


   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 <stdio.h>
  27 #include <stdlib.h>
  28 #include <string.h>
  29 #include <signal.h>
  30 #include <pthread.h>
  31 #include <sys/types.h>
  32 #include <sys/socket.h>
  33 #include <sys/select.h>
  34 #include <sys/time.h>
  35 #include <sys/resource.h>
  36 #include <sys/uio.h>
  37 #include <unistd.h>
  38 #include <errno.h>

  39 #include <sys/poll.h>
  40 
  41 #include "jni_util.h"
  42 
  43 /*
  44  * Stack allocated by thread when doing blocking operation
  45  */
  46 typedef struct threadEntry {
  47     pthread_t thr;                      /* this thread */
  48     struct threadEntry *next;           /* next thread */
  49     int intr;                           /* interrupted */
  50 } threadEntry_t;
  51 
  52 /*
  53  * Heap allocated during initialized - one entry per fd
  54  */
  55 typedef struct {
  56     pthread_mutex_t lock;               /* fd lock */
  57     threadEntry_t *threads;             /* threads blocked on fd */
  58 } fdEntry_t;
  59 
  60 /*
  61  * Signal to unblock thread
  62  */


 324     BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
 325 }
 326 
 327 #ifndef USE_SELECT
 328 int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
 329     BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
 330 }
 331 #else
 332 int NET_Select(int s, fd_set *readfds, fd_set *writefds,
 333                fd_set *exceptfds, struct timeval *timeout) {
 334     BLOCKING_IO_RETURN_INT( s-1,
 335                             select(s, readfds, writefds, exceptfds, timeout) );
 336 }
 337 #endif
 338 
 339 /*
 340  * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399.
 341  * Auto restarts with adjusted timeout if interrupted by
 342  * signal other than our wakeup signal.
 343  */
 344 int NET_Timeout(JNIEnv *env, int s, long timeout) {
 345     long prevtime = 0, newtime;
 346     struct timeval t, *tp = &t;
 347     fd_set fds;
 348     fd_set* fdsp = NULL;
 349     int allocated = 0;
 350     threadEntry_t self;
 351     fdEntry_t *fdEntry = getFdEntry(s);
 352 
 353     /*
 354      * Check that fd hasn't been closed.
 355      */
 356     if (fdEntry == NULL) {
 357         errno = EBADF;
 358         return -1;
 359     }
 360 
 361     /*
 362      * Pick up current time as may need to adjust timeout
 363      */
 364     if (timeout > 0) {
 365         /* Timed */
 366         struct timeval now;
 367         gettimeofday(&now, NULL);
 368         prevtime = now.tv_sec * 1000  +  now.tv_usec / 1000;
 369         t.tv_sec = timeout / 1000;
 370         t.tv_usec = (timeout % 1000) * 1000;
 371     } else if (timeout < 0) {
 372         /* Blocking */
 373         tp = 0;
 374     } else {
 375         /* Poll */
 376         t.tv_sec = 0;
 377         t.tv_usec = 0;
 378     }
 379 
 380     if (s < FD_SETSIZE) {
 381         fdsp = &fds;
 382         FD_ZERO(fdsp);
 383     } else {
 384         int length = (howmany(s+1, NFDBITS)) * sizeof(int);        
 385         fdsp = (fd_set *) calloc(1, length);
 386         if (fdsp == NULL) {
 387             JNU_ThrowOutOfMemoryError(env, "NET_Select native heap allocation failed");
 388             return 0;
 389         }
 390         allocated = 1;
 391     }
 392     FD_SET(s, fdsp);
 393 
 394     for(;;) {

 395         int rv;

 396 
 397         /*
 398          * call select on the fd. If interrupted by our wakeup signal
 399          * errno will be set to EBADF.
 400          */


 401 
 402         startOp(fdEntry, &self);
 403         rv = select(s+1, fdsp, 0, 0, tp);
 404         endOp(fdEntry, &self);
 405 
 406         /*
 407          * If interrupted then adjust timeout. If timeout
 408          * has expired return 0 (indicating timeout expired).
 409          */
 410         if (rv < 0 && errno == EINTR) {
 411             if (timeout > 0) {
 412                 struct timeval now;
 413                 gettimeofday(&now, NULL);
 414                 newtime = now.tv_sec * 1000  +  now.tv_usec / 1000;
 415                 timeout -= newtime - prevtime;
 416                 if (timeout <= 0) {
 417                     if (allocated != 0)
 418                         free(fdsp);
 419                     return 0;
 420                 }
 421                 prevtime = newtime;
 422                 t.tv_sec = timeout / 1000;
 423                 t.tv_usec = (timeout % 1000) * 1000;
 424             }
 425         } else {
 426             if (allocated != 0)
 427                 free(fdsp);
 428             return rv;
 429         }
 430 
 431     }
 432 }