Hey Nick (or anyone else),
What was the exact issue with Async spawning on Windows? I know it's not working but maybe we/I can come up with a work-around and/or help fix it upstream. IIRC last time I tried to enable the #ifdef'd out async code for Windows, there was some glib-async-helper.exe or something like this and when I ran it it crashed everytime, but this was with a quite recent Geany and GLIB and maybe I was mixing Geany bundled GTK+ with my own newer bundle in PATH. Maybe we just need to bundle this utility or something?
If anyone can give a little info on what the problem is and what was tried to fix it, I can probably spend some time this weekend to have (another) shot at fixing it.
P.S. This email has absolutely nothing to do with the commit its replying to except for being related to process spawning on Windows and the Geany Win32 expert might read it :)
Cheers, Matthew Brush
On 12-10-24 09:35 AM, Nick Treleaven wrote:
[...]
On Thu, 25 Oct 2012 16:31:17 -0700 Matthew Brush mbrush@codebrainz.ca wrote:
Hey Nick (or anyone else),
What was the exact issue with Async spawning on Windows? I know it's not working but maybe we/I can come up with a work-around and/or help fix it upstream. IIRC last time I tried to enable the #ifdef'd out async code for Windows, there was some glib-async-helper.exe or something like this and when I ran it it crashed everytime, but this was with a quite recent Geany and GLIB and maybe I was mixing Geany bundled GTK+ with my own newer bundle in PATH.
I'm using Geany on win~1 recently, with gtk+2.16 and glib-2.22 (the minimum versions). g_spawn_async_with_pipes() works fine for me, from a plugin, for a console application, along with the helper.
There are weird I/O effects if Geany is compiled with -mconsole (useful to see the glib/gtk+ messages) and the spawned application is also console, but the default/normal is -mwindows.
Maybe we just need to bundle this utility or something?
Depends on how common the problem is...
On 26/10/2012 17:44, Dimitar Zhekov wrote:
I'm using Geany on win~1 recently, with gtk+2.16 and glib-2.22 (the minimum versions). g_spawn_async_with_pipes() works fine for me, from a plugin, for a console application, along with the helper.
So redirecting I/O works for stdout, stderr and it works for build commands like gcc, make, grep, etc?
IME it sometimes works and sometimes doesn't, and it might depend on which program is being spawned (e.g. which grep you use). I recently checked the commits on the GLib gspawn-win32 code and there didn't seem to be any relevant fixes.
On Fri, 26 Oct 2012 18:44:04 +0100 Nick Treleaven nick.treleaven@btinternet.com wrote:
On 26/10/2012 17:44, Dimitar Zhekov wrote:
I'm using Geany on win~1 recently, with gtk+2.16 and glib-2.22 (the minimum versions). g_spawn_async_with_pipes() works fine for me, from a plugin, for a console application, along with the helper.
So redirecting I/O works for stdout, stderr and it works for build commands like gcc, make, grep, etc?
It works between a console program and the plugin that spawned it, with {PeekNamedPipe() + read()} and {repeat write() on N ms} calls.
Note that instead of EAGAIN, read() may return EINVAL, and write() may return ENOSPC. I have no idea how the higher level I/O functions respond, and I'm doing async spawn, not sync (though it shoudn't differ).
One more thing you must do:
HANDLE h = (HANDLE) _get_osfhandle(fd); DWORD state;
if (h != INVALID_HANDLE_VALUE && GetNamedPipeHandleState(h, &state, NULL, NULL, NULL, NULL, 0)) { state |= PIPE_NOWAIT; if (SetNamedPipeHandleState(h, &state, NULL, NULL)) return TRUE; }
return FALSE;
for all fd-s used, otherwise read() and write() will block.
IME it sometimes works and sometimes doesn't, and it might depend on which program is being spawned (e.g. which grep you use). I recently checked the commits on the GLib gspawn-win32 code and there didn't seem to be any relevant fixes.
The anonymous pipe I/O under Win~1 is not marked as deprecated, but all documentation says to use overlapped I/O (which is no good for us), and the named pipe functions work on anonymous pipes only "for compatibility with MS-DOS LAN Manager" (sic!) IIRC, and may be killed any time. So it's not much of a glib problem...
On 31/10/2012 17:49, Dimitar Zhekov wrote:
On Fri, 26 Oct 2012 18:44:04 +0100 Nick Treleaven nick.treleaven@btinternet.com wrote:
On 26/10/2012 17:44, Dimitar Zhekov wrote:
I'm using Geany on win~1 recently, with gtk+2.16 and glib-2.22 (the minimum versions). g_spawn_async_with_pipes() works fine for me, from a plugin, for a console application, along with the helper.
So redirecting I/O works for stdout, stderr and it works for build commands like gcc, make, grep, etc?
It works between a console program and the plugin that spawned it, with {PeekNamedPipe() + read()} and {repeat write() on N ms} calls.
This confused me. Are you saying you use native Windows functions in combination with g_spawn? I thought only g_io_add_watch could be used.
Note that instead of EAGAIN, read() may return EINVAL, and write() may return ENOSPC. I have no idea how the higher level I/O functions respond, and I'm doing async spawn, not sync (though it shoudn't differ).
One more thing you must do:
HANDLE h = (HANDLE) _get_osfhandle(fd); DWORD state;
if (h != INVALID_HANDLE_VALUE && GetNamedPipeHandleState(h, &state, NULL, NULL, NULL, NULL, 0)) { state |= PIPE_NOWAIT; if (SetNamedPipeHandleState(h, &state, NULL, NULL)) return TRUE; }
return FALSE;
for all fd-s used, otherwise read() and write() will block.
IME it sometimes works and sometimes doesn't, and it might depend on which program is being spawned (e.g. which grep you use). I recently checked the commits on the GLib gspawn-win32 code and there didn't seem to be any relevant fixes.
The anonymous pipe I/O under Win~1 is not marked as deprecated, but all documentation says to use overlapped I/O (which is no good for us), and the named pipe functions work on anonymous pipes only "for compatibility with MS-DOS LAN Manager" (sic!) IIRC, and may be killed any time. So it's not much of a glib problem...
On Thu, 15 Nov 2012 13:06:53 +0000 Nick Treleaven nick.treleaven@btinternet.com wrote:
On 26/10/2012 17:44, Dimitar Zhekov wrote:
I'm using Geany on win~1 recently, with gtk+2.16 and glib-2.22 (the minimum versions). g_spawn_async_with_pipes() works fine for me, from a plugin, for a console application, along with the helper.
So redirecting I/O works for stdout, stderr and it works for build commands like gcc, make, grep, etc?
It works between a console program and the plugin that spawned it, with {PeekNamedPipe() + read()} and {repeat write() on N ms} calls.
This confused me. Are you saying you use native Windows functions in combination with g_spawn? I thought only g_io_add_watch could be used.
g_spawn_async_with_pipes() returns libc/msvcrt fd-s. You can use them to create channels, or directly.
Anonymous win~1 pipe fd-s are handled by giowin like regular fd-s (G_IO_WIN32_FILE_DESC), which causes problems, and I wanted a single g_source with the order of stdin/out/err operations order under my control. So calling read() and write() turned out to be easier. giowin uses them at the lowest level too.
On 16/11/2012 20:31, Dimitar Zhekov wrote:
This confused me. Are you saying you use native Windows functions in combination with g_spawn? I thought only g_io_add_watch could be used.
g_spawn_async_with_pipes() returns libc/msvcrt fd-s. You can use them to create channels, or directly.
Anonymous win~1 pipe fd-s are handled by giowin like regular fd-s (G_IO_WIN32_FILE_DESC), which causes problems, and I wanted a single g_source with the order of stdin/out/err operations order under my control. So calling read() and write() turned out to be easier. giowin uses them at the lowest level too.
OK, thanks for the info.
Am 16.11.2012 21:31, schrieb Dimitar Zhekov:
On Thu, 15 Nov 2012 13:06:53 +0000 Nick Treleaven nick.treleaven@btinternet.com wrote:
On 26/10/2012 17:44, Dimitar Zhekov wrote:
I'm using Geany on win~1 recently, with gtk+2.16 and glib-2.22 (the minimum versions). g_spawn_async_with_pipes() works fine for me, from a plugin, for a console application, along with the helper.
So redirecting I/O works for stdout, stderr and it works for build commands like gcc, make, grep, etc?
It works between a console program and the plugin that spawned it, with {PeekNamedPipe() + read()} and {repeat write() on N ms} calls.
This confused me. Are you saying you use native Windows functions in combination with g_spawn? I thought only g_io_add_watch could be used.
g_spawn_async_with_pipes() returns libc/msvcrt fd-s. You can use them to create channels, or directly.
Anonymous win~1 pipe fd-s are handled by giowin like regular fd-s (G_IO_WIN32_FILE_DESC), which causes problems, and I wanted a single g_source with the order of stdin/out/err operations order under my control. So calling read() and write() turned out to be easier. giowin uses them at the lowest level too.
FWIW, I recently fought with windows fd-s too, but I don't know if it helps in Geany's case. glib's poll() is broken for non-socket fd-s (i.e. broken stdout/stdin). There is a much better poll implementation for win32 available, at pulseaudio (contributed by me, based on gnulib's with some fixes). With that you could, in theory, monitor stdout of another process in a sensible fashion.
Best regards.
On Sat, 17 Nov 2012 20:04:39 +0100 Thomas Martitz thomas.martitz@student.htw-berlin.de wrote:
Am 16.11.2012 21:31, schrieb Dimitar Zhekov:
Anonymous win~1 pipe fd-s are handled by giowin like regular fd-s (G_IO_WIN32_FILE_DESC), which causes problems, [...]
FWIW, I recently fought with windows fd-s too, but I don't know if it helps in Geany's case. glib's poll() is broken for non-socket fd-s (i.e. broken stdout/stdin).
IIRC they block, and simply setting them to non-blocking loads one of the processor cores at 100%, without delivering meaningful results.
There is a much better poll implementation for win32 available, at pulseaudio (contributed by me, based on gnulib's with some fixes). With that you could, in theory, monitor stdout of another process in a sensible fashion.
For POLLIN it's the same as mine. Great minds think alike. :)
For POLLOUT, your version is better, except than any fd for which PeekNamedPipe() returns an error different than ERROR_BROKEN_PIPE is automatically considered OUT. The problem would be how to integrate pa_poll() with glib main loop - g_source_add_poll() is not a regular source, it's supported internally by the context and accesses it's internal poll fields. Pulse has it's own glib-mainloop, but that's a bit on the heavy side... For OUT, I simply call write() at 50ms (configurable), and since Geany on win~1 randomly switches from using 0% CPU time to 6-7%, especially if FF/TB is running, calling write() 20 times per second makes no difference.
Am 23.11.2012 18:45, schrieb Dimitar Zhekov:
For POLLIN it's the same as mine. Great minds think alike. :)
For POLLOUT, your version is better, except than any fd for which PeekNamedPipe() returns an error different than ERROR_BROKEN_PIPE is automatically considered OUT. The problem would be how to integrate pa_poll() with glib main loop - g_source_add_poll() is not a regular source, it's supported internally by the context and accesses it's internal poll fields. Pulse has it's own glib-mainloop, but that's a bit on the heavy side... For OUT, I simply call write() at 50ms (configurable), and since Geany on win~1 randomly switches from using 0% CPU time to 6-7%, especially if FF/TB is running, calling write() 20 times per second makes no difference.
Would trying to get that poll into glib be worthwhile?
Best regards
On Fri, 23 Nov 2012 22:07:40 +0100 Thomas Martitz thomas.martitz@student.htw-berlin.de wrote:
Am 23.11.2012 18:45, schrieb Dimitar Zhekov:
For POLLOUT, your version is better [...] The problem would be how to integrate pa_poll() with glib main loop - g_source_add_poll() is not a regular source [...] Geany on win~1 randomly switches to using _6-7%_ CPU time [...]
Would trying to get that poll into glib be worthwhile?
All things considered, no - unless the glib devs decide to fix it.