diff options
Diffstat (limited to 'winsup/cygwin/cygheap.cc')
-rw-r--r-- | winsup/cygwin/cygheap.cc | 214 |
1 files changed, 18 insertions, 196 deletions
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 639f4e662..9f1a3f513 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -1,7 +1,7 @@ /* cygheap.cc: Cygwin heap manager. Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010, 2011, 2012 Red Hat, Inc. + 2010, 2011 Red Hat, Inc. This file is part of Cygwin. @@ -23,8 +23,6 @@ #include "heap.h" #include "sigproc.h" #include "pinfo.h" -#include "registry.h" -#include "ntdll.h" #include <unistd.h> #include <wchar.h> @@ -47,23 +45,6 @@ struct cygheap_entry char data[0]; }; -class tls_sentry -{ -public: - static muto lock; - int destroy; - void init (); - bool acquired () {return lock.acquired ();} - tls_sentry () {destroy = 0;} - tls_sentry (DWORD wait) {destroy = lock.acquire (wait);} - ~tls_sentry () {if (destroy) lock.release ();} -}; - -muto NO_COPY tls_sentry::lock; -static NO_COPY size_t nthreads; - -#define THREADLIST_CHUNK 256 - #define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0])) #define N0 ((_cmalloc_entry *) NULL) #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (unsigned) (N0->data))) @@ -108,6 +89,23 @@ cygheap_fixup_in_child (bool execed) } } +int +init_cygheap::manage_console_count (const char *something, int amount, bool avoid_freeing_console) +{ + if (console_count == 0 && amount > 0) + init_console_handler (true); + console_count += amount; + debug_printf ("%s: console_count %d, amount %d, %s, avoid_freeing_console %d", + something, console_count, amount, myctty (), avoid_freeing_console); + if (!avoid_freeing_console && amount <= 0 && !console_count && myself->ctty == -1) + { + BOOL res = FreeConsole (); + debug_printf ("freed console, res %d", res); + init_console_handler (false); + } + return console_count; +} + void init_cygheap::close_ctty () { @@ -157,100 +155,6 @@ _csbrk (int sbs) return prebrk; } -/* Use absolute path of cygwin1.dll to derive the Win32 dir which - is our installation_root. Note that we can't handle Cygwin installation - root dirs of more than 4K path length. I assume that's ok... - - This function also generates the installation_key value. It's a 64 bit - hash value based on the path of the Cygwin DLL itself. It's subsequently - used when generating shared object names. Thus, different Cygwin - installations generate different object names and so are isolated from - each other. - - Having this information, the installation key together with the - installation root path is written to the registry. The idea is that - cygcheck can print the paths into which the Cygwin DLL has been - installed for debugging purposes. - - Last but not least, the new cygwin properties datastrcuture is checked - for the "disabled_key" value, which is used to determine whether the - installation key is actually added to all object names or not. This is - used as a last resort for debugging purposes, usually. However, there - could be another good reason to re-enable object name collisions between - multiple Cygwin DLLs, which we're just not aware of right now. Cygcheck - can be used to change the value in an existing Cygwin DLL binary. */ -void -init_cygheap::init_installation_root () -{ - if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX)) - api_fatal ("Can't initialize Cygwin installation root dir.\n" - "GetModuleFileNameW(%p, %p, %u), %E", - cygwin_hmodule, installation_root, PATH_MAX); - PWCHAR p = installation_root; - if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */ - { - p = wcpcpy (p, L"\\??\\"); - GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 4); - } - else - { - bool unc = false; - if (wcsncmp (p + 2, L"?\\", 2)) /* No long path prefix, so UNC path. */ - { - p = wcpcpy (p, L"\\??\\UN"); - GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 6); - *p = L'C'; - unc = true; - } - else if (!wcsncmp (p + 4, L"UNC\\", 4)) /* Native NT UNC path. */ - unc = true; - if (unc) - { - p = wcschr (p + 2, L'\\'); /* Skip server name */ - if (p) - p = wcschr (p + 1, L'\\'); /* Skip share name */ - } - } - installation_root[1] = L'?'; - - RtlInitEmptyUnicodeString (&installation_key, installation_key_buf, - sizeof installation_key_buf); - RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root), - &installation_key, FALSE); - - PWCHAR w = wcsrchr (installation_root, L'\\'); - if (w) - { - *w = L'\0'; - w = wcsrchr (installation_root, L'\\'); - } - if (!w) - api_fatal ("Can't initialize Cygwin installation root dir.\n" - "Invalid DLL path"); - /* If w < p, the Cygwin DLL resides in the root dir of a drive or network - path. In that case, if we strip off yet another backslash, the path - becomes invalid. We avoid that here so that the DLL also works in this - scenario. The /usr/bin and /usr/lib default mounts will probably point - to something non-existing, but that's life. */ - if (w > p) - *w = L'\0'; - - for (int i = 1; i >= 0; --i) - { - reg_key r (i, KEY_WRITE, _WIDE (CYGWIN_INFO_INSTALLATIONS_NAME), - NULL); - if (NT_SUCCESS (r.set_string (installation_key_buf, - installation_root))) - break; - } - - if (cygwin_props.disable_key) - { - installation_key.Length = 0; - installation_key.Buffer[0] = L'\0'; - } -} - void __stdcall cygheap_init () { @@ -273,7 +177,6 @@ cygheap_init () cygheap->fdtab.init (); if (!cygheap->sigs) sigalloc (); - cygheap->init_tls_list (); } /* Copyright (C) 1997, 2000 DJ Delorie */ @@ -563,84 +466,3 @@ cygheap_user::set_name (const char *new_name) cfree_and_set (pdomain); cfree_and_set (pwinname); } - -void -init_cygheap::init_tls_list () -{ - if (threadlist) - memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0])); - else - { - sthreads = THREADLIST_CHUNK; - threadlist = (_cygtls **) ccalloc_abort (HEAP_TLS, cygheap->sthreads, - sizeof (cygheap->threadlist[0])); - } - tls_sentry::lock.init ("thread_tls_sentry"); -} - -void -init_cygheap::add_tls (_cygtls *t) -{ - cygheap->user.reimpersonate (); - tls_sentry here (INFINITE); - if (nthreads >= cygheap->sthreads) - { - threadlist = (_cygtls **) - crealloc_abort (threadlist, (sthreads += THREADLIST_CHUNK) - * sizeof (threadlist[0])); - // memset (threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (threadlist[0])); - } - - threadlist[nthreads++] = t; -} - -void -init_cygheap::remove_tls (_cygtls *t, DWORD wait) -{ - tls_sentry here (wait); - if (here.acquired ()) - { - for (size_t i = 0; i < nthreads; i++) - if (t == threadlist[i]) - { - if (i < --nthreads) - threadlist[i] = threadlist[nthreads]; - debug_only_printf ("removed %p element %d", this, i); - break; - } - } -} - -_cygtls * -init_cygheap::find_tls (int sig) -{ - debug_printf ("sig %d\n", sig); - tls_sentry here (INFINITE); - - static int NO_COPY threadlist_ix; - - _cygtls *t = _main_tls; - - myfault efault; - if (efault.faulted ()) - threadlist[threadlist_ix]->remove (INFINITE); - else - { - threadlist_ix = -1; - while (++threadlist_ix < (int) nthreads) - if (sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig)) - { - t = cygheap->threadlist[threadlist_ix]; - goto out; - } - threadlist_ix = -1; - while (++threadlist_ix < (int) nthreads) - if (!sigismember (&(threadlist[threadlist_ix]->sigmask), sig)) - { - t = cygheap->threadlist[threadlist_ix]; - break; - } - } -out: - return t; -} |