Home Explore Blog CI



postgresql

78th chunk of `doc/src/sgml/libpq.sgml`
e5bdc2829b626ba061ec33da1de23b637509df9d9dbf4d370000000100000fb0
 while waiting for input from the database server.  However,
   it is still possible that the application will block waiting to send
   output to the server.  This is relatively uncommon but can happen if
   very long SQL commands or data values are sent.  (It is much more
   probable if the application sends data via <command>COPY IN</command>,
   however.)  To prevent this possibility and achieve completely
   nonblocking database operation, the following additional functions
   can be used.

   <variablelist>
    <varlistentry id="libpq-PQsetnonblocking">
     <term><function>PQsetnonblocking</function><indexterm><primary>PQsetnonblocking</primary></indexterm></term>

     <listitem>
      <para>
       Sets the nonblocking status of the connection.
<synopsis>
int PQsetnonblocking(PGconn *conn, int arg);
</synopsis>
      </para>

      <para>
       Sets the state of the connection to nonblocking if
       <parameter>arg</parameter> is 1, or blocking if
       <parameter>arg</parameter> is 0.  Returns 0 if OK, -1 if error.
      </para>

      <para>
       In the nonblocking state, successful calls to
       <xref linkend="libpq-PQsendQuery"/>, <xref linkend="libpq-PQputline"/>,
       <xref linkend="libpq-PQputnbytes"/>, <xref linkend="libpq-PQputCopyData"/>,
       and <xref linkend="libpq-PQendcopy"/> will not block;  their changes
       are stored in the local output buffer until they are flushed.
       Unsuccessful calls will return an error and must be retried.
      </para>

      <para>
       Note that <xref linkend="libpq-PQexec"/> does not honor nonblocking
       mode; if it is called, it will act in blocking fashion anyway.
      </para>
     </listitem>
    </varlistentry>

    <varlistentry id="libpq-PQisnonblocking">
     <term><function>PQisnonblocking</function><indexterm><primary>PQisnonblocking</primary></indexterm></term>

     <listitem>
      <para>
       Returns the blocking status of the database connection.
<synopsis>
int PQisnonblocking(const PGconn *conn);
</synopsis>
      </para>

      <para>
       Returns 1 if the connection is set to nonblocking mode and 0 if
       blocking.
      </para>
     </listitem>
    </varlistentry>

    <varlistentry id="libpq-PQflush">
     <term><function>PQflush</function><indexterm><primary>PQflush</primary></indexterm></term>

      <listitem>
       <para>
       Attempts to flush any queued output data to the server.  Returns
       0 if successful (or if the send queue is empty), -1 if it failed
       for some reason, or 1 if it was unable to send all the data in
       the send queue yet (this case can only occur if the connection
       is nonblocking).
<synopsis>
int PQflush(PGconn *conn);
</synopsis>
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>

  <para>
   After sending any command or data on a nonblocking connection, call
   <xref linkend="libpq-PQflush"/>.  If it returns 1, wait for the socket
   to become read- or write-ready.  If it becomes write-ready, call
   <xref linkend="libpq-PQflush"/> again.  If it becomes read-ready, call
   <xref linkend="libpq-PQconsumeInput"/>, then call
   <xref linkend="libpq-PQflush"/> again.  Repeat until
   <xref linkend="libpq-PQflush"/> returns 0.  (It is necessary to check for
   read-ready and drain the input with <xref linkend="libpq-PQconsumeInput"/>,
   because the server can block trying to send us data, e.g., NOTICE
   messages, and won't read our data until we read its.)  Once
   <xref linkend="libpq-PQflush"/> returns 0, wait for the socket to be
   read-ready and then read the response as described above.
  </para>

 </sect1>

 <sect1 id="libpq-pipeline-mode">
  <title>Pipeline Mode</title>

  <indexterm zone="libpq-pipeline-mode">
   <primary>libpq</primary>
   <secondary>pipeline mode</secondary>
  </indexterm>

  <indexterm zone="libpq-pipeline-mode">
   <primary>pipelining</primary>
   <secondary>in libpq</secondary>
  </indexterm>

  <indexterm zone="libpq-pipeline-mode">

Title: Achieving Complete Non-Blocking Database Operations with PQsetnonblocking and PQflush
Summary
This section explains how to achieve fully non-blocking database operations in libpq using `PQsetnonblocking`, `PQisnonblocking`, and `PQflush`. Setting the connection to non-blocking allows `PQsendQuery`, `PQputline`, `PQputnbytes`, `PQputCopyData`, and `PQendcopy` to store changes in a local buffer until flushed. After sending data, `PQflush` should be called, and the application should wait for the socket to become read- or write-ready, calling `PQflush` or `PQconsumeInput` accordingly until `PQflush` returns 0. The section also mentions that `PQexec` doesn't support nonblocking mode.