44 http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm
45 ...
46 The close subroutine is blocked until all subroutines which use the file
47 descriptor return to usr space. For example, when a thread is calling close
48 and another thread is calling select with the same file descriptor, the
49 close subroutine does not return until the select call returns.
50 ...
51 */
52
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <signal.h>
56 #include <pthread.h>
57 #include <sys/types.h>
58 #include <sys/socket.h>
59 #include <sys/time.h>
60 #include <sys/resource.h>
61 #include <sys/uio.h>
62 #include <unistd.h>
63 #include <errno.h>
64
65 #include <sys/poll.h>
66
67 /*
68 * Stack allocated by thread when doing blocking operation
69 */
70 typedef struct threadEntry {
71 pthread_t thr; /* this thread */
72 struct threadEntry *next; /* next thread */
73 int intr; /* interrupted */
74 } threadEntry_t;
75
76 /*
77 * Heap allocated during initialized - one entry per fd
78 */
79 typedef struct {
80 pthread_mutex_t lock; /* fd lock */
81 threadEntry_t *threads; /* threads blocked on fd */
82 } fdEntry_t;
83
84 /*
85 * Signal to unblock thread
86 */
374 BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
375 }
376
377 #ifndef USE_SELECT
378 int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
379 BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
380 }
381 #else
382 int NET_Select(int s, fd_set *readfds, fd_set *writefds,
383 fd_set *exceptfds, struct timeval *timeout) {
384 BLOCKING_IO_RETURN_INT( s-1,
385 select(s, readfds, writefds, exceptfds, timeout) );
386 }
387 #endif
388
389 /*
390 * Wrapper for poll(s, timeout).
391 * Auto restarts with adjusted timeout if interrupted by
392 * signal other than our wakeup signal.
393 */
394 int NET_Timeout(int s, long timeout) {
395 long prevtime = 0, newtime;
396 struct timeval t;
397 fdEntry_t *fdEntry = getFdEntry(s);
398
399 /*
400 * Check that fd hasn't been closed.
401 */
402 if (fdEntry == NULL) {
403 errno = EBADF;
404 return -1;
405 }
406
407 /*
408 * Pick up current time as may need to adjust timeout
409 */
410 if (timeout > 0) {
411 gettimeofday(&t, NULL);
412 prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
413 }
414
|
44 http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm
45 ...
46 The close subroutine is blocked until all subroutines which use the file
47 descriptor return to usr space. For example, when a thread is calling close
48 and another thread is calling select with the same file descriptor, the
49 close subroutine does not return until the select call returns.
50 ...
51 */
52
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <signal.h>
56 #include <pthread.h>
57 #include <sys/types.h>
58 #include <sys/socket.h>
59 #include <sys/time.h>
60 #include <sys/resource.h>
61 #include <sys/uio.h>
62 #include <unistd.h>
63 #include <errno.h>
64 #include <sys/poll.h>
65
66 #include "jni.h"
67
68 /*
69 * Stack allocated by thread when doing blocking operation
70 */
71 typedef struct threadEntry {
72 pthread_t thr; /* this thread */
73 struct threadEntry *next; /* next thread */
74 int intr; /* interrupted */
75 } threadEntry_t;
76
77 /*
78 * Heap allocated during initialized - one entry per fd
79 */
80 typedef struct {
81 pthread_mutex_t lock; /* fd lock */
82 threadEntry_t *threads; /* threads blocked on fd */
83 } fdEntry_t;
84
85 /*
86 * Signal to unblock thread
87 */
375 BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
376 }
377
378 #ifndef USE_SELECT
379 int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
380 BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
381 }
382 #else
383 int NET_Select(int s, fd_set *readfds, fd_set *writefds,
384 fd_set *exceptfds, struct timeval *timeout) {
385 BLOCKING_IO_RETURN_INT( s-1,
386 select(s, readfds, writefds, exceptfds, timeout) );
387 }
388 #endif
389
390 /*
391 * Wrapper for poll(s, timeout).
392 * Auto restarts with adjusted timeout if interrupted by
393 * signal other than our wakeup signal.
394 */
395 int NET_Timeout(JNIEnv *unused, int s, long timeout) {
396 long prevtime = 0, newtime;
397 struct timeval t;
398 fdEntry_t *fdEntry = getFdEntry(s);
399
400 /*
401 * Check that fd hasn't been closed.
402 */
403 if (fdEntry == NULL) {
404 errno = EBADF;
405 return -1;
406 }
407
408 /*
409 * Pick up current time as may need to adjust timeout
410 */
411 if (timeout > 0) {
412 gettimeofday(&t, NULL);
413 prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
414 }
415
|