diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index cf3a7daba..afaee8e97 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -64,6 +64,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) initialized = CYGTLS_INITIALIZED; errno_addr = &(local_clib._errno); locals.cw_timer = NULL; + locals.pathbufs.clear (); if ((void *) func == (void *) cygthread::stub || (void *) func == (void *) cygthread::simplestub) @@ -84,6 +85,7 @@ _cygtls::fixup_after_fork () signal_arrived = NULL; locals.select.sockevt = NULL; locals.cw_timer = NULL; + locals.pathbufs.clear (); wq.thread_ev = NULL; } diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h index b265978f0..018a59946 100644 --- a/winsup/cygwin/local_includes/cygtls.h +++ b/winsup/cygwin/local_includes/cygtls.h @@ -54,10 +54,13 @@ class tls_pathbuf }; uint64_t _counters; }; + HANDLE tls_heap; char *c_buf[TP_NUM_C_BUFS]; WCHAR *w_buf[TP_NUM_W_BUFS]; public: + void clear () { memset (this, 0, sizeof *this); } + void create (); void destroy (); friend class tmp_pathbuf; friend class san; diff --git a/winsup/cygwin/tls_pbuf.cc b/winsup/cygwin/tls_pbuf.cc index f5f318e98..7c8149856 100644 --- a/winsup/cygwin/tls_pbuf.cc +++ b/winsup/cygwin/tls_pbuf.cc @@ -10,22 +10,32 @@ details. */ #define tls_pbuf _my_tls.locals.pathbufs +void +tls_pathbuf::create () +{ + tls_heap = HeapCreate (HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS, + NT_MAX_PATH * sizeof (WCHAR) * 10, /* 640K */ + NT_MAX_PATH * TP_NUM_C_BUFS /* 4.6M */ + + NT_MAX_PATH * TP_NUM_W_BUFS * sizeof (WCHAR)); +} + void tls_pathbuf::destroy () { - for (uint32_t i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i) - free (c_buf[i]); - for (uint32_t i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i) - free (w_buf[i]); + if (tls_heap) + HeapDestroy (tls_heap); } char * tmp_pathbuf::c_get () { + if (!tls_pbuf.tls_heap) + tls_pbuf.create (); if (tls_pbuf.c_cnt >= TP_NUM_C_BUFS) api_fatal ("Internal error: TP_NUM_C_BUFS too small: %u", TP_NUM_C_BUFS); if (!tls_pbuf.c_buf[tls_pbuf.c_cnt] - && !(tls_pbuf.c_buf[tls_pbuf.c_cnt] = (char *) malloc (NT_MAX_PATH))) + && !(tls_pbuf.c_buf[tls_pbuf.c_cnt] + = (char *) HeapAlloc (tls_pbuf.tls_heap, 0, NT_MAX_PATH))) api_fatal ("Internal error: Out of memory for new path buf."); return tls_pbuf.c_buf[tls_pbuf.c_cnt++]; } @@ -33,11 +43,14 @@ tmp_pathbuf::c_get () PWCHAR tmp_pathbuf::w_get () { + if (!tls_pbuf.tls_heap) + tls_pbuf.create (); if (tls_pbuf.w_cnt >= TP_NUM_W_BUFS) api_fatal ("Internal error: TP_NUM_W_BUFS too small: %u.", TP_NUM_W_BUFS); if (!tls_pbuf.w_buf[tls_pbuf.w_cnt] && !(tls_pbuf.w_buf[tls_pbuf.w_cnt] - = (PWCHAR) malloc (NT_MAX_PATH * sizeof (WCHAR)))) + = (PWCHAR) HeapAlloc (tls_pbuf.tls_heap, 0, + NT_MAX_PATH * sizeof (WCHAR)))) api_fatal ("Internal error: Out of memory for new wide path buf."); return tls_pbuf.w_buf[tls_pbuf.w_cnt++]; }