aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/misc.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-01-11 20:12:43 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-01-11 20:12:43 +0000
commit782eefc580a503db4773cd177b17dcc6fd33b058 (patch)
tree047dfd54ec77992eb816e7b2250fec5f584eb1fb /src/backend/utils/adt/misc.c
parentfb627b76ccc4c7074e37b6b94155864f6cbd1b23 (diff)
downloadpostgresql-782eefc580a503db4773cd177b17dcc6fd33b058.tar.gz
postgresql-782eefc580a503db4773cd177b17dcc6fd33b058.zip
Create a standard function pg_sleep() to sleep for a specified amount of time.
Replace the former ad-hoc implementation used in the regression tests. Joachim Wieland
Diffstat (limited to 'src/backend/utils/adt/misc.c')
-rw-r--r--src/backend/utils/adt/misc.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 14bb593c2c2..2ceea8969a5 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.49 2005/10/15 02:49:29 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.50 2006/01/11 20:12:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,6 +17,7 @@
#include <sys/file.h>
#include <signal.h>
#include <dirent.h>
+#include <math.h>
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
@@ -259,3 +260,51 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
FreeDir(fctx->dirdesc);
SRF_RETURN_DONE(funcctx);
}
+
+
+/*
+ * pg_sleep - delay for N seconds
+ */
+Datum
+pg_sleep(PG_FUNCTION_ARGS)
+{
+ float8 secs = PG_GETARG_FLOAT8(0);
+ float8 endtime;
+
+ /*
+ * We break the requested sleep into segments of no more than 1 second,
+ * to put an upper bound on how long it will take us to respond to a
+ * cancel or die interrupt. (Note that pg_usleep is interruptible by
+ * signals on some platforms but not others.) Also, this method avoids
+ * exposing pg_usleep's upper bound on allowed delays.
+ *
+ * By computing the intended stop time initially, we avoid accumulation
+ * of extra delay across multiple sleeps. This also ensures we won't
+ * delay less than the specified time if pg_usleep is interrupted
+ * by other signals such as SIGHUP.
+ */
+
+#ifdef HAVE_INT64_TIMESTAMP
+#define GetNowFloat() ((float8) GetCurrentTimestamp() / 1000000.0)
+#else
+#define GetNowFloat() GetCurrentTimestamp()
+#endif
+
+ endtime = GetNowFloat() + secs;
+
+ for (;;)
+ {
+ float8 delay;
+
+ CHECK_FOR_INTERRUPTS();
+ delay = endtime - GetNowFloat();
+ if (delay >= 1.0)
+ pg_usleep(1000000L);
+ else if (delay > 0.0)
+ pg_usleep((long) ceil(delay * 1000000.0));
+ else
+ break;
+ }
+
+ PG_RETURN_VOID();
+}