diff options
author | Nicholas Clark <nick@ccl4.org> | 2006-02-03 13:06:00 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2006-02-03 13:06:00 +0000 |
commit | 22c96fc102ce8ee52778a2d8a7fced27b492c1ee (patch) | |
tree | 1a1f53570204f0e471c6f8c8f2b2252f40a448d8 /perlio.c | |
parent | f550f1f84120b52f9da4c1bccd557ed73c676650 (diff) | |
download | perl-22c96fc102ce8ee52778a2d8a7fced27b492c1ee.tar.gz |
Change PL_perlio_fd_refcnt from a fixed size static array to a pointer
to a dynamic array.
p4raw-id: //depot/perl@27059
Diffstat (limited to 'perlio.c')
-rw-r--r-- | perlio.c | 54 |
1 files changed, 49 insertions, 5 deletions
@@ -56,8 +56,6 @@ #include "XSUB.h" -#define PERLIO_MAX_REFCOUNTABLE_FD 2048 - #ifdef __Lynx__ /* Missing proto on LynxOS */ int mkstemp(char*); @@ -2247,6 +2245,42 @@ perl_mutex PerlIO_mutex; /* PL_perlio_fd_refcnt[] is in intrpvar.h */ +/* Must be called with PerlIO_mutex locked. */ +static void +S_more_refcounted_fds(pTHX_ const int new_fd) { + const int old_max = PL_perlio_fd_refcnt_size; + const int new_max = 16 + (new_fd & 15); + int *new_array; + + PerlIO_debug("More fds - old=%d, need %d, new=%d\n", + old_max, new_fd, new_max); + + if (new_fd < old_max) { + return; + } + + new_array + = PerlMemShared_realloc(PL_perlio_fd_refcnt, new_max * sizeof(int)); + + if (!new_array) { +#ifdef USE_THREADS + MUTEX_UNLOCK(&PerlIO_mutex); +#endif + /* Can't use PerlIO to write as it allocates memory */ + PerlLIO_write(PerlIO_fileno(Perl_error_log), + PL_no_mem, strlen(PL_no_mem)); + my_exit(1); + } + + PL_perlio_fd_refcnt_size = new_max; + PL_perlio_fd_refcnt = new_array; + + PerlIO_debug("Zeroing %p, %d\n", new_array + old_max, new_max - old_max); + + Zero(new_array + old_max, new_max - old_max, int); +} + + void PerlIO_init(pTHX) { @@ -2260,13 +2294,18 @@ void PerlIOUnix_refcnt_inc(int fd) { dTHX; - if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) { + if (fd >= 0) { dVAR; + #ifdef USE_THREADS MUTEX_LOCK(&PerlIO_mutex); #endif + if (fd >= PL_perlio_fd_refcnt_size) + S_more_refcounted_fds(aTHX_ fd); + PL_perlio_fd_refcnt[fd]++; PerlIO_debug("fd %d refcnt=%d\n",fd,PL_perlio_fd_refcnt[fd]); + #ifdef USE_THREADS MUTEX_UNLOCK(&PerlIO_mutex); #endif @@ -2278,11 +2317,16 @@ PerlIOUnix_refcnt_dec(int fd) { dTHX; int cnt = 0; - if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) { + if (fd >= 0) { dVAR; #ifdef USE_THREADS MUTEX_LOCK(&PerlIO_mutex); #endif + /* XXX should this be a panic? */ + if (fd >= PL_perlio_fd_refcnt_size) + S_more_refcounted_fds(aTHX_ fd); + + /* XXX should this be a panic if it drops below 0? */ cnt = --PL_perlio_fd_refcnt[fd]; PerlIO_debug("fd %d refcnt=%d\n",fd,cnt); #ifdef USE_THREADS @@ -2512,7 +2556,7 @@ PerlIOUnix_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags) if (flags & PERLIO_DUP_FD) { fd = PerlLIO_dup(fd); } - if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) { + if (fd >= 0) { f = PerlIOBase_dup(aTHX_ f, o, param, flags); if (f) { /* If all went well overwrite fd in dup'ed lay with the dup()'ed fd */ |