< prev index next >

src/java.base/linux/native/libnet/linux_close.c

Print this page
rev 13764 : 8150460: (linux|bsd|aix)_close.c: file descriptor table may become large or may not work at all
Reviewed-by:


  42 typedef struct threadEntry {
  43     pthread_t thr;                      /* this thread */
  44     struct threadEntry *next;           /* next thread */
  45     int intr;                           /* interrupted */
  46 } threadEntry_t;
  47 
  48 /*
  49  * Heap allocated during initialized - one entry per fd
  50  */
  51 typedef struct {
  52     pthread_mutex_t lock;               /* fd lock */
  53     threadEntry_t *threads;             /* threads blocked on fd */
  54 } fdEntry_t;
  55 
  56 /*
  57  * Signal to unblock thread
  58  */
  59 static int sigWakeup = (__SIGRTMAX - 2);
  60 
  61 /*
  62  * The fd table and the number of file descriptors












  63  */
  64 static fdEntry_t *fdTable;
  65 static int fdCount;
  66 
  67 /*
  68  * Null signal handler
  69  */
  70 static void sig_wakeup(int sig) {
  71 }
  72 
  73 /*
  74  * Initialization routine (executed when library is loaded)
  75  * Allocate fd tables and sets up signal handler.
  76  */
  77 static void __attribute((constructor)) init() {
  78     struct rlimit nbr_files;
  79     sigset_t sigset;
  80     struct sigaction sa;
  81 
  82     /*
  83      * Allocate table based on the maximum number of
  84      * file descriptors.
  85      */
  86     getrlimit(RLIMIT_NOFILE, &nbr_files);
  87     fdCount = nbr_files.rlim_max;
  88     fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
  89     if (fdTable == NULL) {
  90         fprintf(stderr, "library initialization failed - "
  91                 "unable to allocate file descriptor table - out of memory");
  92         abort();
  93     }
  94 
  95     /*
  96      * Setup the signal handler
  97      */
  98     sa.sa_handler = sig_wakeup;
  99     sa.sa_flags   = 0;
 100     sigemptyset(&sa.sa_mask);
 101     sigaction(sigWakeup, &sa, NULL);
 102 
 103     sigemptyset(&sigset);
 104     sigaddset(&sigset, sigWakeup);
 105     sigprocmask(SIG_UNBLOCK, &sigset, NULL);
 106 }
 107 
 108 /*
 109  * Return the fd table for this fd or NULL is fd out
 110  * of range.
 111  */
 112 static inline fdEntry_t *getFdEntry(int fd)
 113 {
 114     if (fd < 0 || fd >= fdCount) {




 115         return NULL;
 116     }
 117     return &fdTable[fd];



















 118 }
 119 
 120 /*
 121  * Start a blocking operation :-
 122  *    Insert thread onto thread list for the fd.
 123  */
 124 static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
 125 {
 126     self->thr = pthread_self();
 127     self->intr = 0;
 128 
 129     pthread_mutex_lock(&(fdEntry->lock));
 130     {
 131         self->next = fdEntry->threads;
 132         fdEntry->threads = self;
 133     }
 134     pthread_mutex_unlock(&(fdEntry->lock));
 135 }
 136 
 137 /*




  42 typedef struct threadEntry {
  43     pthread_t thr;                      /* this thread */
  44     struct threadEntry *next;           /* next thread */
  45     int intr;                           /* interrupted */
  46 } threadEntry_t;
  47 
  48 /*
  49  * Heap allocated during initialized - one entry per fd
  50  */
  51 typedef struct {
  52     pthread_mutex_t lock;               /* fd lock */
  53     threadEntry_t *threads;             /* threads blocked on fd */
  54 } fdEntry_t;
  55 
  56 /*
  57  * Signal to unblock thread
  58  */
  59 static int sigWakeup = (__SIGRTMAX - 2);
  60 
  61 /*
  62  * The fd table holds one entry per file descriptor.
  63  * Note: the number of possible file descriptors can get quite large;
  64  * RLIMIT_NO_FILE can be large or even infinite.
  65  * Instead of allocating a plain array of RLIMIT_NO_FILE len, we
  66  * allocate a two dimensional sparse array: file descriptors are
  67  * of type int, which on all our platforms is 32bit; so we
  68  * use the upper 16 bit as index into a base table, and the lower
  69  * 16bit as index into the actual entry table; the latter is only
  70  * allocated on demand.
  71  * Usually (<64K file descriptors and file descriptors handed out
  72  * sequentually) there will only be the base table and one entry
  73  * table in slot 0. But this approach handles corner cases like
  74  * large file descriptor values seamlessly.
  75  */
  76 static fdEntry_t** fdTable;
  77 static pthread_mutex_t fdTableLock = PTHREAD_MUTEX_INITIALIZER;
  78 
  79 /*
  80  * Null signal handler
  81  */
  82 static void sig_wakeup(int sig) {
  83 }
  84 
  85 /*
  86  * Initialization routine (executed when library is loaded)
  87  * Allocate fd tables and sets up signal handler.
  88  */
  89 static void __attribute((constructor)) init() {

  90     sigset_t sigset;
  91     struct sigaction sa;
  92 
  93     fdTable = (fdEntry_t**)calloc(0x10000, sizeof(fdEntry_t*));






  94     if (fdTable == NULL) {
  95         fprintf(stderr, "library initialization failed - "
  96                 "unable to allocate file descriptor table - out of memory");
  97         abort();
  98     }
  99 
 100     /*
 101      * Setup the signal handler
 102      */
 103     sa.sa_handler = sig_wakeup;
 104     sa.sa_flags   = 0;
 105     sigemptyset(&sa.sa_mask);
 106     sigaction(sigWakeup, &sa, NULL);
 107 
 108     sigemptyset(&sigset);
 109     sigaddset(&sigset, sigWakeup);
 110     sigprocmask(SIG_UNBLOCK, &sigset, NULL);
 111 }
 112 
 113 /*
 114  * Return the fd table for this fd or NULL is fd out
 115  * of range.
 116  */
 117 static inline fdEntry_t *getFdEntry(int fd)
 118 {
 119     int base_index;
 120     int index;
 121     fdEntry_t* entryTable = NULL;
 122 
 123     if (fd < 0) {
 124         return NULL;
 125     }
 126 
 127     base_index = fd >> 16;
 128     index = fd & 0xFFFF;
 129 
 130     /* Look up the entry table; create it if needed */
 131     pthread_mutex_lock(&fdTableLock);
 132     if (fdTable[base_index] == NULL) {
 133       entryTable = calloc(0x10000, sizeof(fdEntry_t));
 134       if (entryTable == NULL) {
 135         fprintf(stderr, "Unable to allocate file descriptor table - out of memory");
 136         pthread_mutex_unlock(&fdTableLock);
 137         abort();
 138       }
 139       fdTable[base_index] = entryTable;
 140     } else {
 141       entryTable = fdTable[base_index];
 142     }
 143     pthread_mutex_unlock(&fdTableLock);
 144 
 145     return entryTable + index;
 146 }
 147 
 148 /*
 149  * Start a blocking operation :-
 150  *    Insert thread onto thread list for the fd.
 151  */
 152 static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
 153 {
 154     self->thr = pthread_self();
 155     self->intr = 0;
 156 
 157     pthread_mutex_lock(&(fdEntry->lock));
 158     {
 159         self->next = fdEntry->threads;
 160         fdEntry->threads = self;
 161     }
 162     pthread_mutex_unlock(&(fdEntry->lock));
 163 }
 164 
 165 /*


< prev index next >