[PATCH 2/2] kernelbase: Add support for CREATE_NO_WINDOW flag.
Eric Pouech
eric.pouech at orange.fr
Wed Apr 6 04:57:27 CDT 2022
Le 06/04/2022 à 08:34, Eric Pouech a écrit :
>>
>>> this 'next' - aka third - patch, just creates a window less console
>>> in some cases for an initial process and should fix (or at least
>>> improve) a couple of open bugs
>>>
>>> (to make it short, in scenario like "wine foo >& log < /dev/null",
>>> it prevents foo and the subprocesses when in cui subsystem to create
>>> visible consoles)
>>>
>>> (just to share it here)
>>>
>>
>> To recap our private conversation, there are nice things about that
>> solution: it makes such invocation more similar to a more common
>> situation on Windows and I like that aspect. My main concern is that
>> it will make invoking Wine in situations when there is no Unix
>> console available much more expensive, because we'd need to create an
>> extra conhost process that would be useless in majority of cases. I
>> know that we have some users using Wine as part of their Unix
>> scripts, likely ran in the background, for whom it's likely to
>> provide worse performance due to need to create twice as many Wine
>> processes. It may not be a deal breaker, but I think it's a concern
>> that we should consider.
>>
>>
>> One possible solution to that would be, for example, to have
>> something like CONSOLE_HANDLE_SHELL_NO_WINDOW, which would be
>> inherited by CreateProcess(0) and prevent from creating an actual new
>> console. This would achieve most of this patch's goals with lower
>> runtime price.
>>
>>
>> Other possible solution is more specific to Wine tests, which are
>> causing most of those problems. We could just build tests as GUI
>> applications and avoid the problem in the first place. It's not a
>> general solution, through. We could maybe have wineconsole
>> --no-window option that, instead of using AllocConsole, would use
>> CREATE_NO_WINDOW. This would essentially give user an opt-in option
>> to achieve the same outcome as your patch.
>>
>>
>> Anyway, none of above is perfect. I just thrown more ideas to the
>> pool, hoping for your and/or other's opinions.
>>
>>
>> I think that the root of the problem is that there is no single right
>> thing when Wine is invoked by Unix process with no Unix console
>> available (when Unix console is available, the choice to use it is
>> mostly uncontroversial). In some cases, creating a console window is
>> desired, while for others it's not. Currently user is able to force
>> console window creation by running explicitly wineconsole, but the
>> opposite is not possible under assumption that "default" is good for
>> other cases. This is an equivalent of creating the process with
>> DETACHED_PROCESS on Windows.
>>
>
> anyway it would be interesting to have a tool (say wineconsole) where
> we could launch a wine binary with a given console setup (=detached,
> =window, =no-window...); optinonaly, it should also take care of
> redirection of unix std handles (and pass them to subchild)... that
> would require another flag (like --std-inherit). this would allow to
> have an answer to any specific need
>
> I'm all against moving wine tests to GUI subsystem... it doesn't solve
> the bottom line issue: windows "regular" behavior is that CUI
> processes are attached to a console...
>
> yet to decide what's the best option
>
> - for Wine's default for initial process not connected to a unix tty
>
> - for testbot
>
> I'll wait for this to be settled before zero:ing ConsoleHandle for GUI
> processes...
>
>
that patch might work instead
- at least, with it, testbot seems happier on user32:input
(https://testbot.winehq.org/JobDetails.pl?Key=112035&f101=task.log#k101)
- applies on top of the two previous patches
in terms of performance, I measured locally:
4 different settings:
- when starting attached to a unix console
- when starting not attached to a unix console (current wine tree)
- when starting not attached to a unix console (current wine tree +
ALLOC_NO_WINDOW for initial process)
- when starting not attached to a unix console (current wine tree +
SHELL_NO_WINDOW for initial process = the attached patch)
three measures:
==============
in all measures, using time on running tasklist.exe (which only does a
couple of FIXME:s; so a proxy for process startup time - and tear down)
done on bare metal, with a relatively idle machine with "decent" #procs
and memory... so values to be seem as best case, heavier work load might
increase the differences
measure #1:
starting a new wine session: start done 10 times (waiting in between for
wineserver to shut down; with warm up to fill fs caches)
| | /w patch | full session init |
|------------+-----------------+-------------------|
| Unix shell | | 166.3 ms |
| no shell | | 163.7 ms |
| no shell | alloc_no_window | 166 ms |
| no shell | shell_no_window | 164 ms |
roughly, a slight degradation when starting up conhost.exe ; no
measurable difference when not attached to a unix console
measure #2:
keeping an active wine session, starting 1000 times tasklist in a row
| | /w patch | incremental start |
|------------+-----------------+-------------------|
| Unix shell | | 9,440 ms |
| no shell | | 7,903 ms |
| no shell | alloc_no_window | 9,271 ms |
| no shell | shell_no_window | 7,951 ms |
so a 15 to 20% impact on process startup... shell_no_window doesn't show
measurable difference from current situation for non attached processes
measure #3
same logic as measure #2, using start.exe in the middle
| | /w patch | incremental start |
|------------+-----------------+-------------------|
| Unix shell | | 38.315 ms |
| no shell | | 31.945 ms |
| no shell | alloc_no_window | 38.472 ms |
| no shell | shell_no_window | 32.428 ms |
confirms reasults of measure #2, but with a huge impact of start.exe
(path lookup...)
-------------- next part --------------
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c
index 046eee6147c..1a8d1e822b8 100644
--- a/dlls/kernelbase/console.c
+++ b/dlls/kernelbase/console.c
@@ -2303,5 +2303,6 @@ void init_console( void )
if (RtlImageNtHeader( mod )->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
alloc_console( no_window );
}
- else if (params->ConsoleHandle) create_console_connection( params->ConsoleHandle );
+ else if (params->ConsoleHandle && params->ConsoleHandle != CONSOLE_HANDLE_SHELL_NO_WINDOW)
+ create_console_connection( params->ConsoleHandle );
}
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 64117e70abe..2ead6c1fcc3 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -1684,6 +1684,8 @@ static void get_initial_console( RTL_USER_PROCESS_PARAMETERS *params )
params->hStdOutput = (HANDLE)((UINT_PTR)params->hStdOutput | 1);
output_fd = 1;
}
+ if (!params->ConsoleHandle && main_image_info.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI)
+ params->ConsoleHandle = CONSOLE_HANDLE_SHELL_NO_WINDOW;
if (output_fd != -1)
{
diff --git a/include/wine/condrv.h b/include/wine/condrv.h
index 452ce552da1..94afb1d49c4 100644
--- a/include/wine/condrv.h
+++ b/include/wine/condrv.h
@@ -191,5 +191,6 @@ struct condrv_ctrl_event
#define CONSOLE_HANDLE_ALLOC UlongToHandle(1)
#define CONSOLE_HANDLE_ALLOC_NO_WINDOW UlongToHandle(2)
#define CONSOLE_HANDLE_SHELL UlongToHandle(3)
+#define CONSOLE_HANDLE_SHELL_NO_WINDOW UlongToHandle(5)
#endif /* _INC_CONDRV */
More information about the wine-devel
mailing list