libpq WSACleanup is not needed

Started by Andrew Chernowalmost 17 years ago47 messages
#1Andrew Chernow
ac@esilo.com

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock
library, adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

B) Have a way of specifying the behavior, the way it is now or tell
libpq to not initialize wsa at all (kinda like ssl init callbacks).
Leave it up to the application.

I think the WSA startup/cleanup stuff is silly. If I dynamically link
with a DLL, I want it automatically loaded and cleaned up.

Worst case, your app makes lots of connections to different backends.
So, it is constantly doing PQconnectdb and PQfinish; only has a single
conn open at a time. This means its constantly loading and unloading
winsock.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#2Magnus Hagander
magnus@hagander.net
In reply to: Andrew Chernow (#1)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

B) Have a way of specifying the behavior, the way it is now or tell
libpq to not initialize wsa at all (kinda like ssl init callbacks).
Leave it up to the application.

I think the WSA startup/cleanup stuff is silly. If I dynamically link
with a DLL, I want it automatically loaded and cleaned up.

Worst case, your app makes lots of connections to different backends.
So, it is constantly doing PQconnectdb and PQfinish; only has a single
conn open at a time. This means its constantly loading and unloading
winsock.

Option A will make us leak the reference to it though, won't it? And we
are supposed to clean up after ourselves...

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Now, if we actually had libpq_init()/uninit() or something like it, it
would make sense to move it there. But I'm not sure we want to just leak
the reference. But I'm not entirely convinced either way :-)

//Magnus

#3Andrew Chernow
ac@esilo.com
In reply to: Magnus Hagander (#2)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

B) Have a way of specifying the behavior, the way it is now or tell
libpq to not initialize wsa at all (kinda like ssl init callbacks).
Leave it up to the application.

I think the WSA startup/cleanup stuff is silly. If I dynamically link
with a DLL, I want it automatically loaded and cleaned up.

Worst case, your app makes lots of connections to different backends.
So, it is constantly doing PQconnectdb and PQfinish; only has a single
conn open at a time. This means its constantly loading and unloading
winsock.

Option A will make us leak the reference to it though, won't it? And we
are supposed to clean up after ourselves...

Personally, I don't think its the job of libpq to call wsa startup or shutdown.
Pulling it out now will surely break existing apps and piss people off, so I
don't think this is an option. If anything, it should not be a per conn thing.
Its really a library wide thing. Think about it, there is no gain in doing
this per conn. Not to mention, I just found a major issue with it.

Now, if we actually had libpq_init()/uninit() or something like it, it
would make sense to move it there. But I'm not sure we want to just leak
the reference. But I'm not entirely convinced either way :-)

There is probably someone out there that wants wsa to completely unload when
there done using libpq (maybe its a long-lived app like an NT service). The
only thing a leaked ref would do is never unload wsa until the app exited. So,
this is probably bad behavior.

libpq_init() is where an app should elect what libpq should load. If init is
never called, everything should work as it does now. Something like that.
openssl init stuff should be controlled by the same function, maybe some other
components. Auto-init'n is a nice feature most of the time, but it suffers from
ASSuming how and when an app wants to perfom the init.

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Exactely what we did.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#4Alvaro Herrera
alvherre@commandprompt.com
In reply to: Magnus Hagander (#2)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Or perhaps use _init() and _fini() or the Win32 equivalents?

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#5Magnus Hagander
magnus@hagander.net
In reply to: Alvaro Herrera (#4)
Re: libpq WSACleanup is not needed

Alvaro Herrera wrote:

Magnus Hagander wrote:

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Or perhaps use _init() and _fini() or the Win32 equivalents?

You are not allowed to call WSAStartup() and WSACleanup() from these,
since they may load/unload DLLs...

I think you can find traces of that in the cvs history if you're
interested :-D

//Magnus

#6Andrew Chernow
ac@esilo.com
In reply to: Alvaro Herrera (#4)
Re: libpq WSACleanup is not needed

Alvaro Herrera wrote:

Magnus Hagander wrote:

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Or perhaps use _init() and _fini() or the Win32 equivalents?

The Win32 equivalent is DllMain, which I believe only works when your a
dll. Although, from the WSAStartup docs:

"the WSAStartup function should not be called from the DllMain function
in a application DLL. This can potentially cause deadlocks."

That doesn't sound inviting. C++ static intializers would probably
work, if isolated in some small far away distant project file with an
ugly file name.

Outside of user-land work arounds, the real fix would be to have a libpq
library init and shutdown (shutdown only useful for those wanting to
free resources or re-init libpq differently). Not sure there's any
interest in this idea.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#7Merlin Moncure
mmoncure@gmail.com
In reply to: Magnus Hagander (#2)
Re: libpq WSACleanup is not needed

On 1/16/09, Magnus Hagander <magnus@hagander.net> wrote:

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Option A will make us leak the reference to it though, won't it? And we
are supposed to clean up after ourselves...

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Now, if we actually had libpq_init()/uninit() or something like it, it
would make sense to move it there. But I'm not sure we want to just leak
the reference. But I'm not entirely convinced either way :-)

I think init/uninit is the answer. While writing libpqtypes, we noted
that libpq is just plain awkward in a few different ways and probably
deserves a rewrite at some point. not today though....

merlin

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#4)
Re: libpq WSACleanup is not needed

Alvaro Herrera <alvherre@commandprompt.com> writes:

Magnus Hagander wrote:

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Or perhaps use _init() and _fini() or the Win32 equivalents?

I thought we were already relying on DLL load/unload-time calls
in the Win32 port? Or maybe that was a long time ago and we got
rid of it? I agree with Andrew that that would be a saner place
for this than connection start.

regards, tom lane

#9Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#8)
Re: libpq WSACleanup is not needed

Tom Lane wrote:

Alvaro Herrera <alvherre@commandprompt.com> writes:

Magnus Hagander wrote:

If you want to override this behavior today, you can just call
WSAStartup() in your application, and it should never happen. Right?

Or perhaps use _init() and _fini() or the Win32 equivalents?

I thought we were already relying on DLL load/unload-time calls
in the Win32 port? Or maybe that was a long time ago and we got
rid of it? I agree with Andrew that that would be a saner place
for this than connection start.

We had it, and we removed it because the Win32 API docs say you're not
allowed to do it that way because of deadlock risks.

//Magnus

#10Magnus Hagander
magnus@hagander.net
In reply to: Andrew Chernow (#3)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Magnus Hagander wrote:

Andrew Chernow wrote:

WSACleanup is not really needed during a PQfinish. Its horribly slow if
the library ref count is 0 and it actually unloads the winsock library,
adds 225ms to PQfinish.

Solution:
A) Call WSAStartup once and never clean it up. When the app dies, so do
the ref counts and winsock is automatically unloaded.

B) Have a way of specifying the behavior, the way it is now or tell
libpq to not initialize wsa at all (kinda like ssl init callbacks).
Leave it up to the application.

I think the WSA startup/cleanup stuff is silly. If I dynamically link
with a DLL, I want it automatically loaded and cleaned up.

Worst case, your app makes lots of connections to different backends.
So, it is constantly doing PQconnectdb and PQfinish; only has a single
conn open at a time. This means its constantly loading and unloading
winsock.

Option A will make us leak the reference to it though, won't it? And we
are supposed to clean up after ourselves...

Personally, I don't think its the job of libpq to call wsa startup or
shutdown. Pulling it out now will surely break existing apps and piss

I'm afraid it is. Looking at the API docs, the very first paragraph says:
"The WSAStartup function must be the first Windows Sockets function
called by an application or DLL. It allows an application or DLL to
specify the version of Windows Sockets required and retrieve details of
the specific Windows Sockets implementation. The application or DLL can
only issue further Windows Sockets functions after successfully calling
WSAStartup."

Simply put: The API requires we do it.

people off, so I don't think this is an option. If anything, it should
not be a per conn thing. Its really a library wide thing. Think about
it, there is no gain in doing this per conn. Not to mention, I just
found a major issue with it.

That is true, however. I'm not sure I'll agree it's a major issue, but
it's certainly sub-optimal.

The use-case of rapidly creating and dropping connections isn't
particularly common, I think. And there is a perfectly functioning
workaround - something that we should perhaps document in the FAQ or
somewhere in the documentation?

Now, if we actually had libpq_init()/uninit() or something like it, it
would make sense to move it there. But I'm not sure we want to just leak
the reference. But I'm not entirely convinced either way :-)

There is probably someone out there that wants wsa to completely unload
when there done using libpq (maybe its a long-lived app like an NT
service). The only thing a leaked ref would do is never unload wsa
until the app exited. So, this is probably bad behavior.

No, it can also hold internal WSA references and structures.

libpq_init() is where an app should elect what libpq should load. If
init is never called, everything should work as it does now. Something
like that. openssl init stuff should be controlled by the same function,
maybe some other components. Auto-init'n is a nice feature most of the
time, but it suffers from ASSuming how and when an app wants to perfom
the init.

Yeah. So the question is, do we want to bite the bullet and create
init() and uninit() functions for libpq? It'll be a new version of
libpq, and apps will require the new version in order to use it, so it's
a fairly large change to the API.. However, having *had* one, would
certainly have made the SSL fixes that Bruce put in earlier a lot
simpler....

//Magnus

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#10)
Re: libpq WSACleanup is not needed

Magnus Hagander <magnus@hagander.net> writes:

Yeah. So the question is, do we want to bite the bullet and create
init() and uninit() functions for libpq?

I think if calling them is an optimization that improves performance
(by eliminating per-connection-start overhead), this could fly. If
the plan is "we are going to require applications to call these
or they'll break", it's not going to be acceptable ...

regards, tom lane

#12Andrew Chernow
ac@esilo.com
In reply to: Tom Lane (#11)
Re: libpq WSACleanup is not needed

Tom Lane wrote:

Magnus Hagander <magnus@hagander.net> writes:

Yeah. So the question is, do we want to bite the bullet and create
init() and uninit() functions for libpq?

I think if calling them is an optimization that improves performance
(by eliminating per-connection-start overhead), this could fly. If
the plan is "we are going to require applications to call these
or they'll break", it's not going to be acceptable ...

regards, tom lane

My suggestion was to make calling the init/uninit optional (well uninit should
only be optional if init was not called). I think libpq should behave
identically if init() is never called. What init() gets you is the ability to
fine tune libpq (change the default behaviors). For instance: a bit mask
argument to init() called "options", that allows one to toggle things on/off in
libpq: like PG_OPT_NOWSAINIT or PG_OPT_NOSSLINIT. It may requrie something like
to be expandable:

int
PQinit(int info_type, void *info_struct, int options);

I'm just spit-ball'n here. My point is, its could be a good place to allow run
time configuration of libpq.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#13Andrew Chernow
ac@esilo.com
In reply to: Magnus Hagander (#10)
Re: libpq WSACleanup is not needed

Personally, I don't think its the job of libpq to call wsa startup or
shutdown. Pulling it out now will surely break existing apps and piss

I'm afraid it is. Looking at the API docs, the very first paragraph says:
"The WSAStartup function must be the first Windows Sockets function
called by an application or DLL. It allows an application or DLL to
specify the version of Windows Sockets required and retrieve details of
the specific Windows Sockets implementation. The application or DLL can
only issue further Windows Sockets functions after successfully calling
WSAStartup."

I just think libpq should provide a way of turning off built in startups.
Outside of my original per-conn performance concern, an application may want
libpq to use a version of winsock that is different than the one libpq is using.
After reading the very handy doc blurb you so graciously supplied, it appears
to be one of the main reasons wsastartup exists ;-)

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#14James Mansion
james@mansionfamily.plus.com
In reply to: Magnus Hagander (#10)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

The use-case of rapidly creating and dropping connections isn't
particularly common, I think. And there is a perfectly functioning
workaround - something that we should perhaps document in the FAQ or
somewhere in the documentation?

Would it be accetable to do initialise if the number of connections is
changing from 0, and
tidy if the cumber goes back to 0? Applications that retain a
connection would not
suffer the cost on subsequent connect/disconnect.

The init/term is the tidiest way to do it, but the above might help -
perhaps init could just
add a phantom usecount and work the same way.

If you have a DLL for libpq, could you do it in process attach and
detach? Wouldn't
that be the most common case anyway?

James

#15Andrew Chernow
ac@esilo.com
In reply to: James Mansion (#14)
Re: libpq WSACleanup is not needed

James Mansion wrote:

If you have a DLL for libpq, could you do it in process attach and
detach? Wouldn't
that be the most common case anyway?

m$ docs indicate that wsastartup can't be called from dllmain :(

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#16James Mansion
james@mansionfamily.plus.com
In reply to: Andrew Chernow (#15)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

m$ docs indicate that wsastartup can't be called from dllmain :(

OK, fair cop. Says it in the MSDN online version but not in the SDK 6.1
version. :-( Some helper(s)
must start threads I guess.

Re the counting and doing it on first/last socket - of course WSAStartup
counts internally. Prsumably
its only slow when the count is actually going to zero?

Is there a need for a new API to control this - can't you just interpret
another parameter keyword
in PQconnectdb (or the pgoptions string in PQsetdbLogin I guess)?
(Having said that, how
do you control send and receive buffer sizes? Presumably nagle is
always disabled, but those
features could be controlled the same way? Would presumably allow
PGOPTIONS to be
parsed too, though docs 30.12 says that does runtime options for the
server, though
PQconnectdb in 30.1 suggests that it might be parsed for the client
connect too. Maybe.).

James

#17Magnus Hagander
magnus@hagander.net
In reply to: James Mansion (#16)
Re: libpq WSACleanup is not needed

James Mansion wrote:

Andrew Chernow wrote:

m$ docs indicate that wsastartup can't be called from dllmain :(

OK, fair cop. Says it in the MSDN online version but not in the SDK 6.1
version. :-( Some helper(s)
must start threads I guess.

That, and it loads other DLLs as well.

Re the counting and doing it on first/last socket - of course WSAStartup
counts internally. Prsumably
its only slow when the count is actually going to zero?

Yes.

Is there a need for a new API to control this - can't you just interpret
another parameter keyword
in PQconnectdb (or the pgoptions string in PQsetdbLogin I guess)?
(Having said that, how
do you control send and receive buffer sizes? Presumably nagle is
always disabled, but those
features could be controlled the same way? Would presumably allow
PGOPTIONS to be
parsed too, though docs 30.12 says that does runtime options for the
server, though
PQconnectdb in 30.1 suggests that it might be parsed for the client
connect too. Maybe.).

You can always get the socket descriptor back and modify it directly, if
you are sure that what you're changing is supported..

//Magnus

#18Andrew Chernow
ac@esilo.com
In reply to: James Mansion (#16)
Re: libpq WSACleanup is not needed

James Mansion wrote:

Is there a need for a new API to control this - can't you just interpret
another parameter keyword
in PQconnectdb (or the pgoptions string in PQsetdbLogin I guess)?

That's an interesting idea. I don't know if its the correct place to control
this, but it does allow turning off wsastartup and indicating which winsock
version to load.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#19Magnus Hagander
magnus@hagander.net
In reply to: Andrew Chernow (#18)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

James Mansion wrote:

Is there a need for a new API to control this - can't you just
interpret another parameter keyword
in PQconnectdb (or the pgoptions string in PQsetdbLogin I guess)?

That's an interesting idea. I don't know if its the correct place to
control this, but it does allow turning off wsastartup and indicating
which winsock version to load.

From a design perspective it seems like the wrong place to put it if you
think of it as a general initialization. From the narrow perspective of
wsastartup, it could work to add an option to inhibit it. But will it
"scale" to future needs?

//Magnus

#20Andrew Chernow
ac@esilo.com
In reply to: Magnus Hagander (#19)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

Andrew Chernow wrote:

James Mansion wrote:

Is there a need for a new API to control this - can't you just
interpret another parameter keyword
in PQconnectdb (or the pgoptions string in PQsetdbLogin I guess)?

That's an interesting idea. I don't know if its the correct place to
control this, but it does allow turning off wsastartup and indicating
which winsock version to load.

From a design perspective it seems like the wrong place to put it if you

think of it as a general initialization. From the narrow perspective of
wsastartup, it could work to add an option to inhibit it. But will it
"scale" to future needs?

//Magnus

yeah, it might be a stretch. It also ignores the other needs for a
library init().

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#21Bruce Momjian
bruce@momjian.us
In reply to: James Mansion (#14)
Re: libpq WSACleanup is not needed

James Mansion wrote:

Magnus Hagander wrote:

The use-case of rapidly creating and dropping connections isn't
particularly common, I think. And there is a perfectly functioning
workaround - something that we should perhaps document in the FAQ or
somewhere in the documentation?

Would it be accetable to do initialise if the number of connections
is changing from 0, and tidy if the cumber goes back to 0?
Applications that retain a connection would not suffer the cost
on subsequent connect/disconnect.

Yes, we do that now to clear the SSL callbacks in libpq (see
variable 'ssl_open_connections'):

CRYPTO_set_locking_callback(NULL);
CRYPTO_set_id_callback(NULL);

If we don't remove them when going to zero connections then unloading
libpq can cause PHP to crash because it thinks the callback functions
are still loaded.

We could have gone with a more elegant init/uninit solution but there is
a history of slow upstream adoption of libpq API changes.

In this case I am thinking WSACleanup() should probably follow the same
pattern. Having load/unload is superior, but if adoption of that API is
<10%, you will probably get the most advantage for the most users in
making it automatic.

The one big difference with SSL is that the SSL callback unload calls
where cheap, while WSACleanup() is expensive.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#22Andrew Chernow
ac@esilo.com
In reply to: Bruce Momjian (#21)
Re: libpq WSACleanup is not needed

Bruce Momjian wrote:

We could have gone with a more elegant init/uninit solution but there is
a history of slow upstream adoption of libpq API changes.

If that's the case, adding a connectdb option seems like a good
alternative. Orignally suggested here:

http://archives.postgresql.org/pgsql-hackers/2009-01/msg01358.php

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#23Bruce Momjian
bruce@momjian.us
In reply to: Andrew Chernow (#22)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Bruce Momjian wrote:

We could have gone with a more elegant init/uninit solution but there is
a history of slow upstream adoption of libpq API changes.

If that's the case, adding a connectdb option seems like a good
alternative. Orignally suggested here:

http://archives.postgresql.org/pgsql-hackers/2009-01/msg01358.php

Right, well the big question is how many people are going to use the
connection option vs. doing it for everyone automatically.

One possible approach might be to do it automatically, and allow a
connection option to disable the WSACleanup() call.

Actually, right now, if you have two libpq connections, and close one,
does WSACleanup() get called, and does it affect the existing
connection?

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#24Magnus Hagander
magnus@hagander.net
In reply to: Bruce Momjian (#23)
Re: libpq WSACleanup is not needed

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

We could have gone with a more elegant init/uninit solution but there is
a history of slow upstream adoption of libpq API changes.

If that's the case, adding a connectdb option seems like a good
alternative. Orignally suggested here:

http://archives.postgresql.org/pgsql-hackers/2009-01/msg01358.php

Right, well the big question is how many people are going to use the
connection option vs. doing it for everyone automatically.

One possible approach might be to do it automatically, and allow a
connection option to disable the WSACleanup() call.

I think that was the suggestion. Have an option that would disable
*both* the startup and the cleanup call, leaving the responsibility to
the app.

You can do this for SSL today by calling PQinitSSL().

Actually, right now, if you have two libpq connections, and close one,
does WSACleanup() get called, and does it affect the existing
connection?

WSACleanup() gets called, but it has an internal reference count so it
does not have any effect on existing connections.

//Magnus

#25Bruce Momjian
bruce@momjian.us
In reply to: Magnus Hagander (#24)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

We could have gone with a more elegant init/uninit solution but there is
a history of slow upstream adoption of libpq API changes.

If that's the case, adding a connectdb option seems like a good
alternative. Orignally suggested here:

http://archives.postgresql.org/pgsql-hackers/2009-01/msg01358.php

Right, well the big question is how many people are going to use the
connection option vs. doing it for everyone automatically.

One possible approach might be to do it automatically, and allow a
connection option to disable the WSACleanup() call.

I think that was the suggestion. Have an option that would disable
*both* the startup and the cleanup call, leaving the responsibility to
the app.

You can do this for SSL today by calling PQinitSSL().

Right.

Actually, right now, if you have two libpq connections, and close one,
does WSACleanup() get called, and does it affect the existing
connection?

WSACleanup() gets called, but it has an internal reference count so it
does not have any effect on existing connections.

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#26Jeroen Vermeulen
jtv@xs4all.nl
In reply to: Merlin Moncure (#7)
Re: libpq WSACleanup is not needed

Merlin Moncure wrote:

I think init/uninit is the answer. While writing libpqtypes, we noted
that libpq is just plain awkward in a few different ways and probably
deserves a rewrite at some point. not today though....

Would there be any serious harm in:

1. doing the WSAStartup() when the first connection is opened, but
2. cleaning up from either
2a. some kind of on-unload version of DllMain() if possible, or
2b. an explicit new cleanup function

?

(I know it says you can't set the thing up from DllMain, but does it say
something similar about shutdown?)

Jeroen

#27Andrew Chernow
ac@esilo.com
In reply to: Jeroen Vermeulen (#26)
Re: libpq WSACleanup is not needed

Jeroen Vermeulen wrote:

Would there be any serious harm in:

1. doing the WSAStartup() when the first connection is opened, but

The only problem is how to detect the first connection. In a threaded
environment you'd have to perform locking in connectdb, which is
probably not going to fly.

but does it say something similar about shutdown?

From the WSACleanup docs:

"The WSACleanup function typically leads to protocol-specific helper
DLLs being unloaded. As a result, the WSACleanup function should not be
called from the DllMain function in a application DLL. This can
potentially cause deadlocks"

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#28Andrew Chernow
ac@esilo.com
In reply to: Bruce Momjian (#25)
Re: libpq WSACleanup is not needed

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#29Andrew Chernow
ac@esilo.com
In reply to: Andrew Chernow (#28)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I will say, the cleanest solution is still an optional init()/uninit()
for libpq. Has this been ruled out? IMHO, the next best solution is a
connection option.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#30Bruce Momjian
bruce@momjian.us
In reply to: Andrew Chernow (#28)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I assumed it would be like SSL, which is a libpq function call, not a
connection option, e.g. PQinitSSL(), and I think true/false is probably
enough. PQinitSSL info:

If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can use
<function>PQinitSSL(int)</> to tell <application>libpq</application>
that the <acronym>SSL</> library has already been initialized by your
application.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#31Andrew Dunstan
andrew@dunslane.net
In reply to: Andrew Chernow (#29)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I will say, the cleanest solution is still an optional init()/uninit()
for libpq. Has this been ruled out? IMHO, the next best solution is
a connection option.

What happened to the idea of counting connections? That seemed a
relatively clean way to go, I thought, although I haven't followed the
discussion very closely.

cheers

andrew

#32Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#31)
Re: libpq WSACleanup is not needed

Andrew Dunstan wrote:

Andrew Chernow wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I will say, the cleanest solution is still an optional init()/uninit()
for libpq. Has this been ruled out? IMHO, the next best solution is
a connection option.

What happened to the idea of counting connections? That seemed a
relatively clean way to go, I thought, although I haven't followed the
discussion very closely.

I was told WSACleanup does connection counting internally (only the
final close has a performance impact) so there is no need to do the
counting like we do for SSL callbacks.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#33Andrew Chernow
ac@esilo.com
In reply to: Bruce Momjian (#30)
Re: libpq WSACleanup is not needed

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I assumed it would be like SSL, which is a libpq function call, not a
connection option, e.g. PQinitSSL(), and I think true/false is probably
enough. PQinitSSL info:

If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can use
<function>PQinitSSL(int)</> to tell <application>libpq</application>
that the <acronym>SSL</> library has already been initialized by your
application.

That smells dirty to me. How many PQinitXXX() functions are needed
before we drop the XXX and run with PQinit(...)?

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#34Bruce Momjian
bruce@momjian.us
In reply to: Andrew Chernow (#33)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I assumed it would be like SSL, which is a libpq function call, not a
connection option, e.g. PQinitSSL(), and I think true/false is probably
enough. PQinitSSL info:

If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can use
<function>PQinitSSL(int)</> to tell <application>libpq</application>
that the <acronym>SSL</> library has already been initialized by your
application.

That smells dirty to me. How many PQinitXXX() functions are needed
before we drop the XXX and run with PQinit(...)?

Odds are you would still need per-library control over initialization so
I am not sure that helps, i.e. the library initialized WSA already but
needs SSL.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#35Andrew Chernow
ac@esilo.com
In reply to: Bruce Momjian (#34)
Re: libpq WSACleanup is not needed

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I assumed it would be like SSL, which is a libpq function call, not a
connection option, e.g. PQinitSSL(), and I think true/false is probably
enough. PQinitSSL info:

If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can use
<function>PQinitSSL(int)</> to tell <application>libpq</application>
that the <acronym>SSL</> library has already been initialized by your
application.

That smells dirty to me. How many PQinitXXX() functions are needed
before we drop the XXX and run with PQinit(...)?

Odds are you would still need per-library control over initialization so
I am not sure that helps, i.e. the library initialized WSA already but
needs SSL.

That's fine. I solved that issue here:

http://archives.postgresql.org/pgsql-hackers/2009-01/msg01349.php

One of arguments is an "options" bit mask. PG_OPT_LOADSSL,
PG_OPT_LOADWSA, etc... I also suggested a "int inittype, void
*initdata" arguments that can be used now or for future expansion; that
way PQinit is not limited to a single int argument. This could be used
right away with the PG_OPT_LOADWSA idea, to pass the wsa version you want.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#36Bruce Momjian
bruce@momjian.us
In reply to: Andrew Chernow (#35)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Andrew Chernow wrote:

Bruce Momjian wrote:

Ah, OK, so it does its own cleanup on last close, great. I agree a
connection option for this would be good.

What would the option be? "wsainit = [enable | disable]"? Maybe it
should allow setting the version to load: "wsa_version = 2.0". Maybe
the two should be combined: "wsa_version = [default | disable | 2.0]".

I assumed it would be like SSL, which is a libpq function call, not a
connection option, e.g. PQinitSSL(), and I think true/false is probably
enough. PQinitSSL info:

If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can use
<function>PQinitSSL(int)</> to tell <application>libpq</application>
that the <acronym>SSL</> library has already been initialized by your
application.

That smells dirty to me. How many PQinitXXX() functions are needed
before we drop the XXX and run with PQinit(...)?

Odds are you would still need per-library control over initialization so
I am not sure that helps, i.e. the library initialized WSA already but
needs SSL.

That's fine. I solved that issue here:

http://archives.postgresql.org/pgsql-hackers/2009-01/msg01349.php

One of arguments is an "options" bit mask. PG_OPT_LOADSSL,
PG_OPT_LOADWSA, etc... I also suggested a "int inittype, void
*initdata" arguments that can be used now or for future expansion; that
way PQinit is not limited to a single int argument. This could be used
right away with the PG_OPT_LOADWSA idea, to pass the wsa version you want.

That seems overly complex to support just two init functions (we only
had one for SSL for years).

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#37James Mansion
james@mansionfamily.plus.com
In reply to: Andrew Chernow (#27)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

The only problem is how to detect the first connection. In a threaded
environment you'd have to perform locking in connectdb, which is
probably not going to fly.

Well, if you do an atomic test for a flag being zero, and if so then
enter a critsec, do
the init iff you're the first in, and then set the flag on the way out,
then:
- most times, you'll just have the atomic test
- other times, you have a short critsec

I can't see that being a big deal considering you're about to resolve
the server hostname
and then do a TCP/IP connect.

My understanding is that if you do WSAStartup and WSACleanup scoped to
each connection
then:
- the internal counting means that only the 0 -> 1 and 1 -> 0
transitions are expensive
- libpq will only incur the cost if the application didn't do it already

So it seems that the cost is incurred by an application that:
- makes no other use of winsock (or also does startup/cleanup often)
- does not retain a connection (or pool) but creates and closes
a single connection often

How many applications are there that match this pattern? Isn't it
enough just to tell
the user to do WSAStartup and WSACleanup in main() if they find they
have a performance problem? Surely most Windows programs effectively do
that
anyway, often as a side effect of using a framework.

James

#38Magnus Hagander
magnus@hagander.net
In reply to: James Mansion (#37)
Re: libpq WSACleanup is not needed

James Mansion wrote:

Andrew Chernow wrote:

The only problem is how to detect the first connection. In a threaded
environment you'd have to perform locking in connectdb, which is
probably not going to fly.

Well, if you do an atomic test for a flag being zero, and if so then
enter a critsec, do

This is not a problem, we do this in other places in libpq already.

My understanding is that if you do WSAStartup and WSACleanup scoped to
each connection
then:
- the internal counting means that only the 0 -> 1 and 1 -> 0
transitions are expensive
- libpq will only incur the cost if the application didn't do it already

Yes.

So it seems that the cost is incurred by an application that:
- makes no other use of winsock (or also does startup/cleanup often)
- does not retain a connection (or pool) but creates and closes
a single connection often

Correct.

How many applications are there that match this pattern? Isn't it
enough just to tell
the user to do WSAStartup and WSACleanup in main() if they find they
have a performance problem? Surely most Windows programs effectively do
that
anyway, often as a side effect of using a framework.

Yeah, I think an important point here is: If you are willing to call a
special PQinitWinsock() or whatever, then you can just call WSAStartup()
yourself, and the problem goes away...

I guess adding a connection parameter might help a little bit in that
you don't need an extra API call, but I'm unsure if it's worth it given
that the workaround is so simple.

In which case, we should perhaps just document the workaround using
WSAStartup() yourself, and not bother with either API or connection
parameter...

//Magnus

#39Andrew Chernow
ac@esilo.com
In reply to: Magnus Hagander (#38)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

In which case, we should perhaps just document the workaround using
WSAStartup() yourself, and not bother with either API or connection
parameter...

I didn't originally agree with this but now I do. Any libpq init function for
wsa, would only be replacing an app calling WSAStartup themselves. So, why have
it at all.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#40Magnus Hagander
magnus@hagander.net
In reply to: Andrew Chernow (#39)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Magnus Hagander wrote:

In which case, we should perhaps just document the workaround using
WSAStartup() yourself, and not bother with either API or connection
parameter...

I didn't originally agree with this but now I do. Any libpq init
function for wsa, would only be replacing an app calling WSAStartup
themselves. So, why have it at all.

Ok, I think we're fairly agreed that this is the way to proceed then. Do
you want to propose some wording for the documentation, or should I try
to write something myself?

//Magnus

#41Andrew Chernow
ac@esilo.com
In reply to: Magnus Hagander (#40)
Re: libpq WSACleanup is not needed

Magnus Hagander wrote:

Andrew Chernow wrote:

Magnus Hagander wrote:

In which case, we should perhaps just document the workaround using
WSAStartup() yourself, and not bother with either API or connection
parameter...

I didn't originally agree with this but now I do. Any libpq init
function for wsa, would only be replacing an app calling WSAStartup
themselves. So, why have it at all.

Ok, I think we're fairly agreed that this is the way to proceed then. Do
you want to propose some wording for the documentation, or should I try
to write something myself?

//Magnus

I can try. Where should this be documented? ISTM that the best place
is at the top of "30.1 Database Connection Control Functions", since the
issue pertains to any connect/disconnect function. Does that sound
correct? Should it be a warning or just regular text?

First attempt:

"On windows, libpq issues a WSAStartup and WSACleanup on a per
connection basis. Each WSAStartup increments an internal reference
count which is decremented by WSACleanup. Calling WSACleanup with a
reference count of zero, forces all resources to be freed and DLLs to be
unloaded. This is an expensive operation that can take as much as
300ms. This overhead can be seen if an application does not call
WSAStartup and it closes its last PGconn. To avoid this, an application
should manually call WSAStartup."

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#42Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Chernow (#41)
Re: libpq WSACleanup is not needed

Andrew Chernow <ac@esilo.com> writes:

I can try. Where should this be documented? ISTM that the best place
is at the top of "30.1 Database Connection Control Functions", since the
issue pertains to any connect/disconnect function. Does that sound
correct? Should it be a warning or just regular text?

Minor platform-specific performance nits are not that important. Think
"footnote", not "warning at the top of the page".

regards, tom lane

#43Andrew Chernow
ac@esilo.com
In reply to: Tom Lane (#42)
1 attachment(s)
Re: libpq WSACleanup is not needed

Tom Lane wrote:

Andrew Chernow <ac@esilo.com> writes:

I can try. Where should this be documented? ISTM that the best place
is at the top of "30.1 Database Connection Control Functions", since the
issue pertains to any connect/disconnect function. Does that sound
correct? Should it be a warning or just regular text?

Minor platform-specific performance nits are not that important. Think
"footnote", not "warning at the top of the page".

regards, tom lane

Its a footnote at the end of the first paragraph in 30.1.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

Attachments:

wsa.patchtext/plain; name=wsa.patchDownload
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.275
diff -C6 -r1.275 libpq.sgml
*** doc/src/sgml/libpq.sgml	10 Jan 2009 20:14:30 -0000	1.275
--- doc/src/sgml/libpq.sgml	22 Jan 2009 16:51:31 -0000
***************
*** 59,72 ****
     is obtained from the function <function>PQconnectdb</> or
     <function>PQsetdbLogin</>.  Note that these functions will always
     return a non-null object pointer, unless perhaps there is too
     little memory even to allocate the <structname>PGconn</> object.
     The <function>PQstatus</> function should be called to check
     whether a connection was successfully made before queries are sent
!    via the connection object.
! 
     <variablelist>
      <varlistentry>
       <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</></></term>
       <listitem>
        <para>
         Makes a new connection to the database server.
--- 59,84 ----
     is obtained from the function <function>PQconnectdb</> or
     <function>PQsetdbLogin</>.  Note that these functions will always
     return a non-null object pointer, unless perhaps there is too
     little memory even to allocate the <structname>PGconn</> object.
     The <function>PQstatus</> function should be called to check
     whether a connection was successfully made before queries are sent
!    via the connection object.  For windows applications, destroying a
!    <structname>PGconn</> can be expensive in a few case.
!     <footnote>
!      <para>
!       On windows, libpq issues a WSAStartup and WSACleanup on a per 
!       connection basis.  Each WSAStartup increments an internal reference 
!       count which is decremented by WSACleanup.  Calling WSACleanup with 
!       a reference count of zero, forces all resources to be freed and 
!       DLLs to be unloaded.  This is an expensive operation that can take 
!       as much as 300ms.  This overhead can be seen if an application does 
!       not call WSAStartup and it closes its last PGconn.  To avoid this, 
!       an application should manually call WSAStartup.
!      </para>
!     </footnote>
     <variablelist>
      <varlistentry>
       <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</></></term>
       <listitem>
        <para>
         Makes a new connection to the database server.
#44Andrew Chernow
ac@esilo.com
In reply to: Andrew Chernow (#43)
1 attachment(s)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Tom Lane wrote:

Andrew Chernow <ac@esilo.com> writes:

I can try. Where should this be documented? ISTM that the best
place is at the top of "30.1 Database Connection Control Functions",
since the issue pertains to any connect/disconnect function. Does
that sound correct? Should it be a warning or just regular text?

Minor platform-specific performance nits are not that important. Think
"footnote", not "warning at the top of the page".

Its a footnote at the end of the first paragraph in 30.1.

Fixed a few things.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

Attachments:

wsa.patchtext/plain; name=wsa.patchDownload
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.275
diff -C6 -r1.275 libpq.sgml
*** doc/src/sgml/libpq.sgml	10 Jan 2009 20:14:30 -0000	1.275
--- doc/src/sgml/libpq.sgml	22 Jan 2009 17:13:09 -0000
***************
*** 59,72 ****
     is obtained from the function <function>PQconnectdb</> or
     <function>PQsetdbLogin</>.  Note that these functions will always
     return a non-null object pointer, unless perhaps there is too
     little memory even to allocate the <structname>PGconn</> object.
     The <function>PQstatus</> function should be called to check
     whether a connection was successfully made before queries are sent
!    via the connection object.
! 
     <variablelist>
      <varlistentry>
       <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</></></term>
       <listitem>
        <para>
         Makes a new connection to the database server.
--- 59,84 ----
     is obtained from the function <function>PQconnectdb</> or
     <function>PQsetdbLogin</>.  Note that these functions will always
     return a non-null object pointer, unless perhaps there is too
     little memory even to allocate the <structname>PGconn</> object.
     The <function>PQstatus</> function should be called to check
     whether a connection was successfully made before queries are sent
!    via the connection object.  For windows applications, destroying a
!    <structname>PGconn</> can be expensive in a few cases.
!     <footnote>
!      <para>
!       On windows, libpq issues a WSAStartup and WSACleanup on a per 
!       connection basis.  Each WSAStartup increments an internal reference 
!       count which is decremented by WSACleanup.  When calling WSACleanup 
!       with a reference count of zero, all resources will be freed and all 
!       DLLs will be unloaded.  This is an expensive operation that can take 
!       as much as 300ms.  The overhead can be seen if an application does 
!       not call WSAStartup and it closes its last <structname>PGconn</>.  To avoid this, 
!       an application should manually call WSAStartup.
!      </para>
!     </footnote>
     <variablelist>
      <varlistentry>
       <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</></></term>
       <listitem>
        <para>
         Makes a new connection to the database server.
#45Bruce Momjian
bruce@momjian.us
In reply to: Andrew Chernow (#44)
1 attachment(s)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Andrew Chernow wrote:

Tom Lane wrote:

Andrew Chernow <ac@esilo.com> writes:

I can try. Where should this be documented? ISTM that the best
place is at the top of "30.1 Database Connection Control Functions",
since the issue pertains to any connect/disconnect function. Does
that sound correct? Should it be a warning or just regular text?

Minor platform-specific performance nits are not that important. Think
"footnote", not "warning at the top of the page".

Its a footnote at the end of the first paragraph in 30.1.

Fixed a few things.

I have applied a modified version of this documentation patch, attached.
Thanks.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

Attachments:

/rtmp/difftext/x-diffDownload
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.275
diff -c -c -r1.275 libpq.sgml
*** doc/src/sgml/libpq.sgml	10 Jan 2009 20:14:30 -0000	1.275
--- doc/src/sgml/libpq.sgml	6 Feb 2009 18:17:55 -0000
***************
*** 63,68 ****
--- 63,83 ----
     The <function>PQstatus</> function should be called to check
     whether a connection was successfully made before queries are sent
     via the connection object.
+   
+    <note>
+     <para>
+      On Windows, there is a way to improve performance if a single
+      database connection is repeated started and shutdown.  Internally,
+      libpq calls WSAStartup() and WSACleanup() for connection startup
+      and shutdown, respectively.  WSAStartup() increments an internal
+      Windows library reference count which is decremented by WSACleanup().
+      When the reference count is just one, calling WSACleanup() frees
+      all resources and all DLLs are unloaded.  This is an expensive
+      operation.  To avoid this, an application can manually call
+      WSAStartup() so resources will not be freed when the last database
+      connection is closed.
+     </para>
+    </note>
  
     <variablelist>
      <varlistentry>
#46Andrew Chernow
ac@esilo.com
In reply to: Bruce Momjian (#45)
Re: libpq WSACleanup is not needed

Bruce Momjian wrote:

Andrew Chernow wrote:

Andrew Chernow wrote:

Tom Lane wrote:

Andrew Chernow <ac@esilo.com> writes:

I can try. Where should this be documented? ISTM that the best
place is at the top of "30.1 Database Connection Control Functions",
since the issue pertains to any connect/disconnect function. Does
that sound correct? Should it be a warning or just regular text?

Minor platform-specific performance nits are not that important. Think
"footnote", not "warning at the top of the page".

Its a footnote at the end of the first paragraph in 30.1.

Fixed a few things.

I have applied a modified version of this documentation patch, attached.
Thanks.

"connection is repeated started and shutdown."

"repeated" should be "repeatedly".

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

#47Bruce Momjian
bruce@momjian.us
In reply to: Andrew Chernow (#46)
Re: libpq WSACleanup is not needed

Andrew Chernow wrote:

Bruce Momjian wrote:

Andrew Chernow wrote:

Andrew Chernow wrote:

Tom Lane wrote:

Andrew Chernow <ac@esilo.com> writes:

I can try. Where should this be documented? ISTM that the best
place is at the top of "30.1 Database Connection Control Functions",
since the issue pertains to any connect/disconnect function. Does
that sound correct? Should it be a warning or just regular text?

Minor platform-specific performance nits are not that important. Think
"footnote", not "warning at the top of the page".

Its a footnote at the end of the first paragraph in 30.1.

Fixed a few things.

I have applied a modified version of this documentation patch, attached.
Thanks.

"connection is repeated started and shutdown."

"repeated" should be "repeatedly".

Thanks, fixed.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +