< prev index next >

src/java.base/aix/native/libnet/aix_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,8 ---- /* ! * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 2016, SAP SE 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
*** 48,57 **** --- 49,60 ---- and another thread is calling select with the same file descriptor, the close subroutine does not return until the select call returns. ... */ + #include <assert.h> + #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <pthread.h> #include <sys/types.h>
*** 84,97 **** * Signal to unblock thread */ static int sigWakeup = (SIGRTMAX - 1); /* ! * The fd table and the number of file descriptors ! */ ! static fdEntry_t *fdTable = NULL; ! static int fdCount = 0; /* * Null signal handler */ static void sig_wakeup(int sig) { --- 87,122 ---- * Signal to unblock thread */ static int sigWakeup = (SIGRTMAX - 1); /* ! * 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) {
*** 106,151 **** */ void aix_close_init() { struct rlimit nbr_files; sigset_t sigset; struct sigaction sa; ! /* Check already initialized */ ! if (fdCount > 0 && fdTable != NULL) { ! return; ! } ! /* ! * Allocate table based on the maximum number of ! * file descriptors. ! */ ! if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) { ! fprintf(stderr, "library initialization failed - " ! "unable to get max # of allocated fds\n"); ! abort(); ! } ! fdCount = nbr_files.rlim_max; ! /* ! * We have a conceptual problem here, when the number of files is ! * unlimited. As a kind of workaround, we ensure the table is big ! * enough for handle even a large number of files. Since SAP itself ! * recommends a limit of 32000 files, we just use 64000 as 'infinity'. ! */ ! if (nbr_files.rlim_max == RLIM_INFINITY) { ! fdCount = 64000; ! } ! 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(); } ! { ! int i; ! for (i=0; i < fdCount; i++) { ! pthread_mutex_init(&fdTable[i].lock, NULL); } } /* * Setup the signal handler --- 131,174 ---- */ void aix_close_init() { struct rlimit nbr_files; sigset_t sigset; struct sigaction sa; + int i = 0; ! assert(fdTable == NULL); ! /* 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
*** 159,177 **** 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. --- 182,234 ---- 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 >