Re: Reconnect a single connection used by multiple threads in embedded SQL in C application causes error. - Mailing list pgsql-bugs

From Noah Misch
Subject Re: Reconnect a single connection used by multiple threads in embedded SQL in C application causes error.
Date
Msg-id 20220402072749.GC3719101@rfd.leadboat.com
Whole thread Raw
In response to RE: Reconnect a single connection used by multiple threads in embedded SQL in C application causes error.  ("egashira.yusuke@fujitsu.com" <egashira.yusuke@fujitsu.com>)
List pgsql-bugs
On Fri, Mar 25, 2022 at 01:34:16PM +0000, egashira.yusuke@fujitsu.com wrote:
> > On Fri, Mar 04, 2022 at 11:49:39AM +0000, egashira.yusuke@fujitsu.com wrote:
> > > @@ -222,10 +222,15 @@ EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>
> > >    <para>
> > >     The <replaceable>connection-name</replaceable> is used to handle
> > >     multiple connections in one program.  It can be omitted if a
> > > -   program uses only one connection.  The most recently opened
> > > -   connection becomes the current connection, which is used by default
> > > -   when an SQL statement is to be executed (see later in this
> > > -   chapter).
> > > +   program uses only one connection.
> > > +  </para>
> > > +
> > > +  <para>
> > > +   The most recently opened connection becomes the current connection.
> > 
> > This is true.  Disconnecting also changes the current connection, to another
> > one of the open connections.  Please document that somewhere appropriate.
> 
> I have added that behavior to the "Closing a Connection" section.

I intended to ask you to document it such that the reader can predict which
connection becomes the current connection.  Just saying "another" doesn't give
the reader enough information to rely on any particular behavior.  Having said
that, I've changed my mind about documenting this.  The current behavior is
hard to use, particularly in a multithreaded program.  Also, we might want to
change it later.  Moreover, I think it's intuitive that use of current
connection is undefined if one closes current connection and does not later
initialize some connection.  Let's try to leave this disconnect matter
undocumented after all.

> --- a/doc/src/sgml/ecpg.sgml
> +++ b/doc/src/sgml/ecpg.sgml
> @@ -222,10 +222,18 @@ EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>
>    <para>
>     The <replaceable>connection-name</replaceable> is used to handle
>     multiple connections in one program.  It can be omitted if a
> -   program uses only one connection.  The most recently opened
> -   connection becomes the current connection, which is used by default
> -   when an SQL statement is to be executed (see later in this
> -   chapter).
> +   program uses only one connection.
> +  </para>
> +
> +  <para>
> +   The most recently opened connection becomes the current connection.
> +   If your application uses multiple threads, each thread has its own
> +   current connection, and it is the most recently opened connection
> +   in each thread.  Threads that have not yet opened the current
> +   connection treat the most recently opened connection in the
> +   application as the current connection.  The current connection is
> +   used by default when an SQL statement is to be executed (see later
> +   in this chapter).
>    </para>

Disconnects can make this false.

> @@ -435,10 +442,24 @@ EXEC SQL DISCONNECT <optional><replaceable>connection</replaceable></optional>;
>     closed.
>    </para>
>  
> +  <para>
> +   Disconnecting changes the current connection to another opened
> +   connection if the closed connection was the current connection.
> +  </para>
> +
>    <para>
>     It is good style that an application always explicitly disconnect
>     from every connection it opened.
>    </para>
> +
> +  <note>
> +    <para>
> +     Connections are shared among all threads.  Be careful not to
> +     disconnect a connection that is to be used in another thread.

In your original example, I suspect the program author would not think of the
closed connection as "to be used in" Thread#1.  I'm not sure what to write
here, but I feel this isn't it.  We could probably omit the two sentences
without replacing them.

> +     In particular, the behavior is undefined if a connection treated as
> +     the current connection in one thread is closed by another thread.

Contrary to this text, it's okay to close the global current connection, so
long as that connection is not the thread-specific current connection of any
thread other than the current thread.  (This is so awkward.)  It is safe even
though the connection in question would be the current connection of every
thread not having initiated a connection.  The "undefined if the current
thread is not the thread that opened" wording I suggested in my last message
was also flawed, because SET CONNECTION or a disconnect can cause the
thread-specific current connection to become a connection opened in a
different thread.

I'm surprised to find how hard it is to document this without introducing a
false statement.



pgsql-bugs by date:

Previous
From: PG Bug reporting form
Date:
Subject: BUG #17454: Using psql without ipv4 address,the inet_server_port do not return PORT.
Next
From: "David G. Johnston"
Date:
Subject: Re: BUG #17454: Using psql without ipv4 address,the inet_server_port do not return PORT.