Re: Streaming Replication on win32 - Mailing list pgsql-hackers

From Magnus Hagander
Subject Re: Streaming Replication on win32
Date
Msg-id 9837222c1002140652m38813f2atf90968c11daab84d@mail.gmail.com
Whole thread Raw
In response to Re: Streaming Replication on win32  (Fujii Masao <masao.fujii@gmail.com>)
Responses Re: Streaming Replication on win32
List pgsql-hackers
2010/2/8 Fujii Masao <masao.fujii@gmail.com>:
> On Mon, Jan 18, 2010 at 11:46 PM, Magnus Hagander <magnus@hagander.net> wrote:
>>>> From what I can tell, this indicates that pq_getbyte_if_available() is
>>>> not working - because it's supposed to never block, right?
>>>
>>> Right, it's not supposed to block.
>>>
>>>> This could be because the win32 socket emulation layer simply wasn't
>>>> designed to deal with non-blocking sockets. Specifically, it actually
>>>> *always* sets the socket to non-blocking mode, and then uses that to
>>>> properly emulate how sockets work under unix.
>>>
>>> I presume the win32 emulation layer can be taught about non-blocking
>>> sockets? Or maybe pq_getbyte_if_available() can be implemented using
>>> some other simpler method on Windows.
>>
>> It could be taught that, but it would probably be a lot easier to put
>> platform specific code in pq_getbyte_if_available().
>
> Umm.. in this case, for SSL on win32 case, we also need to create
> new function like my_sock_read_if_available() that receives data
> from non-blocking socket, and reassign it to the SSL BIO function.
> Right? If so, it seems easier for me to tell the win32 layer about
> non-blocking.

Sorry about the delay in responding to this.

Remember that the win32 code *always* puts the socket in non-blocking
mode. So we can't just "teach the layer about it". We need some way to
pass the information down that this is actually something we want to
be non-blocking, and it can't be the normal flag on the socket. I
don't really have an idea of where else we'd put it though :( It's in
the port structure, but not beyond it.

What we could do, is have an ugly global flag specifically for the
use-case we have here. Assuming we do create a plataform specific
pq_getbyte_if_available(), the code-path that would have trouble now
would be when we call pq_getbyte_if_available(), and it in turns asks
the socket if there is data, there is, but we end up calling back into
the SSL code to fetch the data, and it gets an incomplete packet.
Correct? So the path is basically:

pq_getbyte_if_available() -> secure_read() -> SSL_read() ->
my_sock_read() -> pgwin32_recv()

Given that we know we are working on a single socket here, we could
use a global flag to tell pgwin32_recv() to become nonblocking. We
could set this flag directly in the win32-specific version of
pq_getbyte_if_available(), and make sure it's cleared as soon as we
exit.

It will obviously fail if we do anything on a *different* socket
during this time, so it has to be set for a very short time. But that
seems doable. And we don't call any socket stuff from signal handlers
so that shouldn't cause issues.


-- Magnus HaganderMe: http://www.hagander.net/Work: http://www.redpill-linpro.com/


pgsql-hackers by date:

Previous
From: Magnus Hagander
Date:
Subject: Re: [NOVICE] Python verison for build in config.pl (Win32)
Next
From: Simon Riggs
Date:
Subject: Optimizing GetConflictingVirtualXIDs()