Home Explore Blog CI



postgresql

77th chunk of `doc/src/sgml/libpq.sgml`
eaf77f253c9a73cca7f86ff27459900fe94857b68321be350000000100000fb2
 check
       <xref linkend="libpq-PQisBusy"/> and/or
       <function>PQnotifies</function> to see if their state has changed.
      </para>

      <para>
       <xref linkend="libpq-PQconsumeInput"/> can be called even if the
       application is not prepared to deal with a result or notification
       just yet.  The function will read available data and save it in
       a buffer, thereby causing a <function>select()</function>
       read-ready indication to go away.  The application can thus use
       <xref linkend="libpq-PQconsumeInput"/> to clear the
       <function>select()</function> condition immediately, and then
       examine the results at leisure.
      </para>
     </listitem>
    </varlistentry>

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

     <listitem>
      <para>
       Returns 1 if a command is busy, that is,
       <xref linkend="libpq-PQgetResult"/> would block waiting for input.
       A 0 return indicates that <xref linkend="libpq-PQgetResult"/> can be
       called with assurance of not blocking.
<synopsis>
int PQisBusy(PGconn *conn);
</synopsis>
      </para>

      <para>
       <xref linkend="libpq-PQisBusy"/> will not itself attempt to read data
       from the server; therefore <xref linkend="libpq-PQconsumeInput"/>
       must be invoked first, or the busy state will never end.
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>

  <para>
   A typical application using these functions will have a main loop that
   uses <function>select()</function> or <function>poll()</function> to wait for
   all the conditions that it must respond to.  One of the conditions
   will be input available from the server, which in terms of
   <function>select()</function> means readable data on the file
   descriptor identified by <xref linkend="libpq-PQsocket"/>.  When the main
   loop detects input ready, it should call
   <xref linkend="libpq-PQconsumeInput"/> to read the input.  It can then
   call <xref linkend="libpq-PQisBusy"/>, followed by
   <xref linkend="libpq-PQgetResult"/> if <xref linkend="libpq-PQisBusy"/>
   returns false (0).  It can also call <function>PQnotifies</function>
   to detect <command>NOTIFY</command> messages (see <xref
   linkend="libpq-notify"/>).
  </para>

  <para>
   A client that uses
   <xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/>
   can also attempt to cancel a command that is still being processed
   by the server; see <xref linkend="libpq-cancel"/>.  But regardless of
   the return value of <xref linkend="libpq-PQcancelBlocking"/>, the application
   must continue with the normal result-reading sequence using
   <xref linkend="libpq-PQgetResult"/>.  A successful cancellation will
   simply cause the command to terminate sooner than it would have
   otherwise.
  </para>

  <para>
   By using the functions described above, it is possible to avoid
   blocking 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>

Title: Non-Blocking Operations and Connection Management in libpq
Summary
This section elaborates on achieving non-blocking behavior with libpq by using `PQconsumeInput` and `PQisBusy` to manage server input. A typical application loop involves using `select()` or `poll()` to monitor server input, then calling `PQconsumeInput`, `PQisBusy`, and `PQgetResult` accordingly. The client can attempt to cancel a command with `PQcancelBlocking`, while still following the standard result-reading sequence. It also introduces `PQsetnonblocking` to prevent blocking when sending large SQL commands or data to the server and `PQiswritable` to check if writing to the server would block.