* ntdll.h (struct _PEB): Add EnvironmentUpdateCount member.
* spawn.cc (child_info_spawn::worker): Speed up job recognition. Expand comment to explain every little detail and so we never forget. * wincap.h (wincaps::has_program_compatibility_assitant): New element. * wincap.cc: Implement above element throughout.
This commit is contained in:
parent
e86c278998
commit
1cb1472404
|
@ -1,3 +1,11 @@
|
||||||
|
2012-02-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* ntdll.h (struct _PEB): Add EnvironmentUpdateCount member.
|
||||||
|
* spawn.cc (child_info_spawn::worker): Speed up job recognition. Expand
|
||||||
|
comment to explain every little detail and so we never forget.
|
||||||
|
* wincap.h (wincaps::has_program_compatibility_assitant): New element.
|
||||||
|
* wincap.cc: Implement above element throughout.
|
||||||
|
|
||||||
2012-02-17 Corinna Vinschen <corinna@vinschen.de>
|
2012-02-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* mount.cc (get_disk_type): Drop unneeded toupper call. Convert case
|
* mount.cc (get_disk_type): Drop unneeded toupper call. Convert case
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009, 2010, 2011 Red Hat, Inc.
|
2009, 2010, 2011, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -689,7 +689,9 @@ typedef struct _PEB
|
||||||
BYTE Reserved3[4];
|
BYTE Reserved3[4];
|
||||||
PVOID ProcessHeap;
|
PVOID ProcessHeap;
|
||||||
PRTL_CRITICAL_SECTION FastPebLock;
|
PRTL_CRITICAL_SECTION FastPebLock;
|
||||||
BYTE Reserved4[436];
|
BYTE Reserved4[8];
|
||||||
|
ULONG EnvironmentUpdateCount;
|
||||||
|
BYTE Reserved5[424];
|
||||||
ULONG SessionId;
|
ULONG SessionId;
|
||||||
} PEB, *PPEB;
|
} PEB, *PPEB;
|
||||||
|
|
||||||
|
|
|
@ -455,17 +455,42 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
|
|
||||||
c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT;
|
c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT;
|
||||||
|
|
||||||
/* We're adding the CREATE_BREAKAWAY_FROM_JOB flag here to workaround issues
|
if (wincap.has_program_compatibility_assitant ())
|
||||||
with the "Program Compatibility Assistant (PCA) Service" observed on
|
{
|
||||||
Windows 7. For some reason, when starting long running sessions from
|
/* We're adding the CREATE_BREAKAWAY_FROM_JOB flag here to workaround
|
||||||
mintty, the affected svchost.exe process takes more and more memory and
|
issues with the "Program Compatibility Assistant (PCA) Service"
|
||||||
at one point takes over the CPU. At this point the machine becomes
|
starting with Windows Vista. For some reason, when starting long
|
||||||
unresponsive. The only way to get back to normal is to stop the entire
|
running sessions from mintty(*), the affected svchost.exe process
|
||||||
mintty session, or to stop the PCA service. However, a process which
|
takes more and more memory and at one point takes over the CPU. At
|
||||||
is controlled by PCA is part of a compatibility job, which allows child
|
this point the machine becomes unresponsive. The only way to get
|
||||||
processes to break away from the job. This helps to avoid this issue. */
|
back to normal is to stop the entire mintty session, or to stop the
|
||||||
|
PCA service. However, a process which is controlled by PCA is part
|
||||||
|
of a compatibility job, which allows child processes to break away
|
||||||
|
from the job. This helps to avoid this issue.
|
||||||
|
|
||||||
|
(*) Note that this is not mintty's fault. It has just been observed
|
||||||
|
with mintty in the first place. See the archives for more info:
|
||||||
|
http://cygwin.com/ml/cygwin-developers/2012-02/msg00018.html */
|
||||||
|
|
||||||
JOBOBJECT_BASIC_LIMIT_INFORMATION jobinfo;
|
JOBOBJECT_BASIC_LIMIT_INFORMATION jobinfo;
|
||||||
if (QueryInformationJobObject (NULL, JobObjectBasicLimitInformation,
|
|
||||||
|
/* Calling QueryInformationJobObject costs time. Starting with
|
||||||
|
Windows XP there's a function IsProcessInJob, which fetches the
|
||||||
|
information whether or not we're part of a job 20 times faster than
|
||||||
|
the call to QueryInformationJobObject. But we're still
|
||||||
|
supporting Windows 2000, so we can't just link to that function.
|
||||||
|
On the other hand, loading the function pointer at runtime is a
|
||||||
|
time comsuming operation, too. So, what we do here is to emulate
|
||||||
|
the IsProcessInJob function when called for the own process and with
|
||||||
|
a NULL job handle. In this case it just returns the value of the
|
||||||
|
lowest bit from PEB->EnvironmentUpdateCount (observed with WinDbg).
|
||||||
|
The name of this PEB member is the same in all (inofficial)
|
||||||
|
documentations of the PEB. Apparently it's a bit misleading.
|
||||||
|
As a result, we only call QueryInformationJobObject if we're on
|
||||||
|
Vista or later *and* if the PEB indicates we're running in a job.
|
||||||
|
Tested on Vista/32, Vista/64, W7/32, W7/64, W8/64. */
|
||||||
|
if ((NtCurrentTeb ()->Peb->EnvironmentUpdateCount & 1) != 0
|
||||||
|
&& QueryInformationJobObject (NULL, JobObjectBasicLimitInformation,
|
||||||
&jobinfo, sizeof jobinfo, NULL)
|
&jobinfo, sizeof jobinfo, NULL)
|
||||||
&& (jobinfo.LimitFlags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK
|
&& (jobinfo.LimitFlags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK
|
||||||
| JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
|
| JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
|
||||||
|
@ -473,6 +498,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
debug_printf ("Add CREATE_BREAKAWAY_FROM_JOB");
|
debug_printf ("Add CREATE_BREAKAWAY_FROM_JOB");
|
||||||
c_flags |= CREATE_BREAKAWAY_FROM_JOB;
|
c_flags |= CREATE_BREAKAWAY_FROM_JOB;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == _P_DETACH)
|
if (mode == _P_DETACH)
|
||||||
c_flags |= DETACHED_PROCESS;
|
c_flags |= DETACHED_PROCESS;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
capability class to the appropriate values.
|
capability class to the appropriate values.
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009, 2010, 2011 Red Hat, Inc.
|
2009, 2010, 2011, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:false,
|
has_stack_size_param_is_a_reservation:false,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -85,6 +86,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
|
||||||
has_stack_size_param_is_a_reservation:false,
|
has_stack_size_param_is_a_reservation:false,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -117,6 +119,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:true,
|
has_stack_size_param_is_a_reservation:true,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -149,6 +152,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:true,
|
has_stack_size_param_is_a_reservation:true,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -181,6 +185,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:true,
|
has_stack_size_param_is_a_reservation:true,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -213,6 +218,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:true,
|
has_stack_size_param_is_a_reservation:true,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:true,
|
wow64_has_secondary_stack:true,
|
||||||
|
has_program_compatibility_assitant:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -245,6 +251,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:true,
|
has_stack_size_param_is_a_reservation:true,
|
||||||
has_console_logon_sid:false,
|
has_console_logon_sid:false,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
|
@ -277,6 +284,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_stack_size_param_is_a_reservation:true,
|
has_stack_size_param_is_a_reservation:true,
|
||||||
has_console_logon_sid:true,
|
has_console_logon_sid:true,
|
||||||
wow64_has_secondary_stack:false,
|
wow64_has_secondary_stack:false,
|
||||||
|
has_program_compatibility_assitant:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* wincap.h: Header for OS capability class.
|
/* wincap.h: Header for OS capability class.
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009, 2010, 2011 Red Hat, Inc.
|
2009, 2010, 2011, 2012 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ struct wincaps
|
||||||
unsigned has_stack_size_param_is_a_reservation : 1;
|
unsigned has_stack_size_param_is_a_reservation : 1;
|
||||||
unsigned has_console_logon_sid : 1;
|
unsigned has_console_logon_sid : 1;
|
||||||
unsigned wow64_has_secondary_stack : 1;
|
unsigned wow64_has_secondary_stack : 1;
|
||||||
|
unsigned has_program_compatibility_assitant : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
|
@ -94,6 +95,7 @@ public:
|
||||||
bool IMPLEMENT (has_stack_size_param_is_a_reservation)
|
bool IMPLEMENT (has_stack_size_param_is_a_reservation)
|
||||||
bool IMPLEMENT (has_console_logon_sid)
|
bool IMPLEMENT (has_console_logon_sid)
|
||||||
bool IMPLEMENT (wow64_has_secondary_stack)
|
bool IMPLEMENT (wow64_has_secondary_stack)
|
||||||
|
bool IMPLEMENT (has_program_compatibility_assitant)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue