+/*********************************************************************
+ *
+ * Function : privoxy_millisleep
+ *
+ * Description : Sleep a number of milliseconds
+ *
+ * Parameters :
+ * 1 : delay: Number of milliseconds to sleep
+ *
+ * Returns : -1 on error, 0 otherwise
+ *
+ *********************************************************************/
+int privoxy_millisleep(unsigned milliseconds)
+{
+#ifdef HAVE_NANOSLEEP
+ struct timespec rqtp = {0};
+ struct timespec rmtp = {0};
+
+ rqtp.tv_sec = milliseconds / 1000;
+ rqtp.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
+
+ return nanosleep(&rqtp, &rmtp);
+#elif defined (_WIN32)
+ Sleep(milliseconds);
+
+ return 0;
+#elif defined(__OS2__)
+ DosSleep(milliseconds * 10);
+
+ return 0;
+#else
+#warning Missing privoxy_milisleep() implementation. delay-response{} will not work.
+
+ return -1;
+#endif /* def HAVE_NANOSLEEP */
+
+}
+
+
+/*********************************************************************
+ *
+ * Function : privoxy_gmtime_r
+ *
+ * Description : Behave like gmtime_r() and convert a
+ * time_t to a struct tm.
+ *
+ * Parameters :
+ * 1 : time_spec: The time to convert
+ * 2 : result: The struct tm to use as storage
+ *
+ * Returns : Pointer to the result or NULL on error.
+ *
+ *********************************************************************/
+struct tm *privoxy_gmtime_r(const time_t *time_spec, struct tm *result)
+{
+ struct tm *timeptr;
+
+#ifdef HAVE_GMTIME_R
+ timeptr = gmtime_r(time_spec, result);
+#elif defined(MUTEX_LOCKS_AVAILABLE)
+ privoxy_mutex_lock(&gmtime_mutex);
+ timeptr = gmtime(time_spec);
+#else
+#warning Using unlocked gmtime()
+ timeptr = gmtime(time_spec);
+#endif
+
+ if (timeptr == NULL)
+ {
+#if !defined(HAVE_GMTIME_R) && defined(MUTEX_LOCKS_AVAILABLE)
+ privoxy_mutex_unlock(&gmtime_mutex);
+#endif
+ return NULL;
+ }
+
+#if !defined(HAVE_GMTIME_R)
+ *result = *timeptr;
+ timeptr = result;
+#ifdef MUTEX_LOCKS_AVAILABLE
+ privoxy_mutex_unlock(&gmtime_mutex);
+#endif
+#endif
+
+ return timeptr;
+}
+