Re: Sometimes the output to the stdout in Windows disappears
От | Alexander Lakhin |
---|---|
Тема | Re: Sometimes the output to the stdout in Windows disappears |
Дата | |
Msg-id | b32688da-fafc-bbf6-b786-2dd7d0a4d578@gmail.com обсуждение исходный текст |
Ответ на | Re: Sometimes the output to the stdout in Windows disappears (Tom Lane <tgl@sss.pgh.pa.us>) |
Ответы |
Re: Sometimes the output to the stdout in Windows disappears
|
Список | pgsql-hackers |
16.10.2020 19:18, Tom Lane wrote:
Oh, very interesting.stderr is affected too. Just replacing stdout with stderr in connect.c and 000_connect.pl gives the same result.Now that you have it somewhat in captivity, maybe you could determine some things: 1. Is it only stdout that's affected? What of other stdio streams? (Note that testing stderr might be tricky because it's probably line-buffered.)
Moreover, the following modification:
...
outfile = fopen("out", "w");
...
fprintf(stdout, "stdout test\n");
fprintf(stderr, "stderr test\n");
fprintf(outfile, "outfile test\n");
WSACleanup();
...
---
for (my $i =0; $i < 100000; $i++) {
unlink('out');
IPC::Run::run(\@cmd, '>', \$stdout, '2>', \$stderr);
open(my $fh, '<', 'out') or die $!;
my $fileout = <$fh>;
ok(defined $fileout && $fileout ne '');
close($fh);
}
detects similar failures too. (On a fail the out file exists but has zero size.)
"fflush(NULL);" just before or after WSACleanup() fixes things.2. Does an fflush() just before, or just after, WSACleanup() fix it?
I've managed to record in ProcMon the activity log for a failed run (aside normal runs). Excerpts from the log are attached. As we can see, the failed process doesn't even try to write into IPC-Run's temp file.
But now we see that the WSACleanup call is a global thing by itself.Depending on your answers to the above, maybe some hack like this would be acceptable: free(conn); #ifdef WIN32 + fflush(NULL); WSACleanup(); #endif } It's not very nice for a library to be doing global things like that, but if the alternative is loss of output, maybe we should.
What bothers me is:But wait a minute: I just looked at Microsoft's docs [1] and found In a multithreaded environment, WSACleanup terminates Windows Sockets operations for all threads. This makes me (a) wonder if that explains the side-effects on stdio, and (b) question why libpq is calling WSACleanup at all. What if we arranged to call WSAStartup just once, during the first libpq connection-open in a process, and then never did WSACleanup? Surely the OS can cope with that, and it eliminates any risk that WSACleanup breaks something.
There must be a call to WSACleanup for each successful call to WSAStartup. Only the final WSACleanup function call performs the actual cleanup. The preceding calls simply decrement an internal reference count in the WS2_32.DLL.So third-party application developers should understand that when using libpq they would have to call WSACleanup one more time to perform "the actual cleanup". (And thus WSAStartup is kind of like a global thing too.)
But may be it's a way better than to have a confirmed risk of losing data.
Best regards,
Alexander
Вложения
В списке pgsql-hackers по дате отправления: