25
25
*
26
26
*
27
27
* IDENTIFICATION
28
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.84 2002/10/16 02:55:30 momjian Exp $
28
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.85 2002/10/24 23:35:55 tgl Exp $
29
29
*
30
30
*-------------------------------------------------------------------------
31
31
*/
@@ -779,18 +779,27 @@ pqFlush(PGconn *conn)
779
779
int
780
780
pqWait (int forRead , int forWrite , PGconn * conn )
781
781
{
782
- return pqWaitTimed (forRead , forWrite , conn , -1 );
782
+ return pqWaitTimed (forRead , forWrite , conn , ( time_t ) - 1 );
783
783
}
784
784
785
+ /*
786
+ * pqWaitTimed: wait, but not past finish_time.
787
+ *
788
+ * If finish_time is exceeded then we return failure (EOF). This is different
789
+ * from the response for a kernel exception (return 0) because we don't want
790
+ * the caller to try to read/write in that case.
791
+ *
792
+ * finish_time = ((time_t) -1) disables the wait limit.
793
+ */
785
794
int
786
795
pqWaitTimed (int forRead , int forWrite , PGconn * conn , time_t finish_time )
787
796
{
788
797
fd_set input_mask ;
789
798
fd_set output_mask ;
790
799
fd_set except_mask ;
791
-
792
800
struct timeval tmp_timeout ;
793
801
struct timeval * ptmp_timeout = NULL ;
802
+ int selresult ;
794
803
795
804
if (conn -> sock < 0 )
796
805
{
@@ -820,24 +829,26 @@ pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
820
829
FD_SET (conn -> sock , & output_mask );
821
830
FD_SET (conn -> sock , & except_mask );
822
831
823
- if (finish_time != -1 )
832
+ if (finish_time != (( time_t ) - 1 ) )
824
833
{
825
834
/*
826
- * select() may modify timeout argument on some platforms so
827
- * use copy.
828
- * XXX Do we really want to do that? If select() returns
829
- * the number of seconds remaining, we are resetting
830
- * the timeout to its original value. This will yeild
831
- * incorrect timings when select() is interrupted.
832
- * bjm 2002-10-14
835
+ * Set up delay. Assume caller incremented finish_time
836
+ * so that we can error out as soon as time() passes it.
837
+ * Note we will recalculate delay each time through the loop.
833
838
*/
834
- if ((tmp_timeout .tv_sec = finish_time - time (NULL )) < 0 )
835
- tmp_timeout .tv_sec = 0 ; /* possible? */
839
+ time_t now = time (NULL );
840
+
841
+ if (finish_time > now )
842
+ tmp_timeout .tv_sec = finish_time - now ;
843
+ else
844
+ tmp_timeout .tv_sec = 0 ;
836
845
tmp_timeout .tv_usec = 0 ;
837
846
ptmp_timeout = & tmp_timeout ;
838
847
}
839
- if (select (conn -> sock + 1 , & input_mask , & output_mask ,
840
- & except_mask , ptmp_timeout ) < 0 )
848
+
849
+ selresult = select (conn -> sock + 1 , & input_mask , & output_mask ,
850
+ & except_mask , ptmp_timeout );
851
+ if (selresult < 0 )
841
852
{
842
853
if (SOCK_ERRNO == EINTR )
843
854
goto retry5 ;
@@ -846,6 +857,12 @@ pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
846
857
SOCK_STRERROR (SOCK_ERRNO ));
847
858
return EOF ;
848
859
}
860
+ if (selresult == 0 )
861
+ {
862
+ printfPQExpBuffer (& conn -> errorMessage ,
863
+ libpq_gettext ("timeout expired\n" ));
864
+ return EOF ;
865
+ }
849
866
}
850
867
851
868
return 0 ;
0 commit comments