summaryrefslogtreecommitdiff
path: root/perlio.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2006-02-03 13:06:00 +0000
committerNicholas Clark <nick@ccl4.org>2006-02-03 13:06:00 +0000
commit22c96fc102ce8ee52778a2d8a7fced27b492c1ee (patch)
tree1a1f53570204f0e471c6f8c8f2b2252f40a448d8 /perlio.c
parentf550f1f84120b52f9da4c1bccd557ed73c676650 (diff)
downloadperl-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.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/perlio.c b/perlio.c
index bee91ee8dc..c2633f9239 100644
--- a/perlio.c
+++ b/perlio.c
@@ -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 */