Hi

Can anyone explain why gwthread is using the poll function to sleep (using 
milliseconds as timeout), and not maybe the select function (using microseconds 
as timeout)?

We have the requirement to be able to sleep for less than a millisecond, which 
the current gwthread_sleep can't provide.

Below is a patch to do just that, using the select function.
I have tested it, so if anyone has any comments, please let me hear them.

The diff is from our own SVN repository, but as far as I know, it is up-to-date 
with the cvs.


Index: gwthread.h
===================================================================
--- gwthread.h  (revision 459)
+++ gwthread.h  (working copy)
@@ -113,7 +113,7 @@
  * call. Returns the internal thread id and the process id. */
 void gwthread_self_ids(long *tid, long *pid);

-/* If the other thread is currently in gwthread_pollfd or gwthread_sleep,
+/* If the other thread is currently in gwthread_pollfd, gwthread_sleep, or 
gwthread_sleep_micro,
  * make it return immediately.  Otherwise, make it return immediately, the
  * next time it calls one of those functions. */
 void gwthread_wakeup(long thread);
@@ -142,6 +142,10 @@
  * calls gwthread_wakeup on us.  Fractional seconds are allowed. */
 void gwthread_sleep(double seconds);

+/* Sleep until "seconds" seconds have elapsed, or until another thread
+ * calls gwthread_wakeup on us.  Fractional seconds are allowed. */
+void gwthread_sleep_micro(double dseconds);
+
 /* Force a specific thread to terminate. Returns 0 on success, -1 if the
  * thread has been terminated while calling and non-zero for the pthread
  * specific error code.


AND


Index: gwthread-pthread.c
===================================================================
--- gwthread-pthread.c  (revision 459)
+++ gwthread-pthread.c  (working copy)
@@ -780,6 +780,42 @@
 }


+void gwthread_sleep_micro(double dseconds)
+{
+    fd_set fd_set_recv;
+    struct threadinfo *threadinfo;
+    int fd;
+    int ret;
+
+    threadinfo = getthreadinfo();
+    fd = threadinfo->wakefd_recv;
+
+    FD_ZERO(&fd_set_recv);
+    FD_SET(fd, &fd_set_recv);
+
+    if (dseconds < 0) {
+        ret = select(fd + 1, &fd_set_recv, NULL, NULL, NULL);
+    }
+    else {
+        struct timeval timeout;
+        timeout.tv_sec = dseconds;
+        timeout.tv_usec = (dseconds - timeout.tv_sec) * 1000000;
+
+        ret = select(fd + 1, &fd_set_recv, NULL, NULL, &timeout);
+    }
+
+    if (ret < 0) {
+        if (errno != EINTR && errno != EAGAIN) {
+            warning(errno, "gwthread_sleep_micro: error in select()");
+        }
+    }
+
+    if (FD_ISSET(fd, &fd_set_recv)) {
+        flushpipe(fd);
+    }
+}
+
+
 int gwthread_cancel(long thread)
 {
     struct threadinfo *threadinfo;






Regards
Werner





Reply via email to