< prev index next >

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

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

*** 1,7 **** /* ! * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 21,30 **** --- 21,32 ---- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ + #include <assert.h> + #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <pthread.h> #include <sys/types.h>
*** 57,70 **** * Signal to unblock thread */ static int sigWakeup = (__SIGRTMAX - 2); /* ! * The fd table and the number of file descriptors ! */ ! static fdEntry_t *fdTable; ! static int fdCount; /* * Null signal handler */ static void sig_wakeup(int sig) { --- 59,94 ---- * Signal to unblock thread */ static int sigWakeup = (__SIGRTMAX - 2); /* ! * fdTable holds one entry per file descriptor, up to a certain ! * maximum. ! * Theoretically, the number of possible file descriptors can get ! * large, though usually it does not. To save memory, we keep file ! * descriptors with large numerical values in an overflow table. That ! * table is organized as a two-dimensional sparse array, allocated ! * on demand. ! */ ! ! static fdEntry_t* fdTable; ! /* Max. number of file descriptors in fdTable. */ ! static const int fdTableMaxSize = 0x1000; /* 4K */ ! /* Max. theoretical number of file descriptor on system. */ ! static int fdLimit; ! /* Length of fdTable, in number of entries. */ ! static int fdTableLen; ! ! /* Overflow table: organized as array of n slabs, each holding ! * 64k entries. ! */ ! static fdEntry_t** fdOverflowTable; ! /* Number of slabs in the overflow table */ ! static int fdOverflowTableLen; ! /* Number of entries in one slab */ ! static const int fdOverflowTableSlabSize = 0x10000; /* 64k */ ! pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER; /* * Null signal handler */ static void sig_wakeup(int sig) {
*** 76,97 **** */ static void __attribute((constructor)) init() { struct rlimit nbr_files; sigset_t sigset; struct sigaction sa; ! /* ! * Allocate table based on the maximum number of ! * file descriptors. ! */ getrlimit(RLIMIT_NOFILE, &nbr_files); ! fdCount = nbr_files.rlim_max; ! fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); if (fdTable == NULL) { fprintf(stderr, "library initialization failed - " "unable to allocate file descriptor table - out of memory"); abort(); } /* * Setup the signal handler */ --- 100,142 ---- */ static void __attribute((constructor)) init() { struct rlimit nbr_files; sigset_t sigset; struct sigaction sa; + int i = 0; ! /* Determine the maximum number of possible file descriptors. */ getrlimit(RLIMIT_NOFILE, &nbr_files); ! if (nbr_files.rlim_max != RLIM_INFINITY) { ! fdLimit = nbr_files.rlim_max; ! } else { ! /* We just do not know. */ ! fdLimit = INT_MAX; ! } ! ! /* Allocate table for low value file descriptors. */ ! fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize; ! fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t)); if (fdTable == NULL) { fprintf(stderr, "library initialization failed - " "unable to allocate file descriptor table - out of memory"); abort(); + } else { + for (i = 0; i < fdTableLen; i ++) { + pthread_mutex_init(&fdTable[i].lock, NULL); + } + } + + /* Allocate overflow table, if needed */ + if (fdLimit > fdTableMaxSize) { + fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1; + fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*)); + if (fdOverflowTable == NULL) { + fprintf(stderr, "library initialization failed - " + "unable to allocate file descriptor overflow table - out of memory"); + abort(); + } } /* * Setup the signal handler */
*** 104,122 **** sigaddset(&sigset, sigWakeup); sigprocmask(SIG_UNBLOCK, &sigset, NULL); } /* ! * Return the fd table for this fd or NULL is fd out ! * of range. */ static inline fdEntry_t *getFdEntry(int fd) { ! if (fd < 0 || fd >= fdCount) { return NULL; } ! return &fdTable[fd]; } /* * Start a blocking operation :- * Insert thread onto thread list for the fd. --- 149,203 ---- sigaddset(&sigset, sigWakeup); sigprocmask(SIG_UNBLOCK, &sigset, NULL); } /* ! * Return the fd table for this fd. */ static inline fdEntry_t *getFdEntry(int fd) { ! fdEntry_t* result = NULL; ! ! if (fd < 0) { return NULL; } ! ! /* This should not happen. If it does, our assumption about ! * max. fd value was wrong. */ ! assert(fd < fdLimit); ! ! if (fd < fdTableMaxSize) { ! assert(fd < fdTableLen); ! result = fdTable + fd; ! } else { ! const int indexInOverflowTable = fd - fdTableMaxSize; ! const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize; ! const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize; ! assert(rootindex < fdOverflowTableLen); ! assert(slabindex < fdOverflowTableSlabSize); ! pthread_mutex_lock(&fdOverflowTableLock); ! if (fdOverflowTable[rootindex] == NULL) { ! fdEntry_t* const newSlab = ! (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t)); ! if (newSlab == NULL) { ! fprintf(stderr, "Unable to allocate file descriptor table - out of memory"); ! pthread_mutex_unlock(&fdOverflowTableLock); ! abort(); ! } else { ! int i; ! for (i = 0; i < fdOverflowTableSlabSize; i ++) { ! pthread_mutex_init(&newSlab[i].lock, NULL); ! } ! fdOverflowTable[rootindex] = newSlab; ! } ! } ! pthread_mutex_unlock(&fdOverflowTableLock); ! result = fdOverflowTable[rootindex] + slabindex; ! } ! ! return result; ! } /* * Start a blocking operation :- * Insert thread onto thread list for the fd.
< prev index next >