Просмотр исходного кода

Unix port: improve support for the Hurd

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
Joan Lledó 6 лет назад
Родитель
Сommit
2f5305c259
2 измененных файлов с 33 добавлено и 9 удалено
  1. 6 4
      contrib/ports/unix/check/CMakeLists.txt
  2. 27 5
      contrib/ports/unix/port/sys_arch.c

+ 6 - 4
contrib/ports/unix/check/CMakeLists.txt

@@ -4,12 +4,14 @@ set (CMAKE_CONFIGURATION_TYPES "Debug;Release")
 
 project(lwipunittests C)
 
-if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    message(FATAL_ERROR "Unit test are currently only working on Linux or Darwin")
+if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "GNU")
+    message(FATAL_ERROR "Unit test are currently only working on Linux, Darwin or Hurd")
 endif()
 
 set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
-set(LWIP_USE_SANITIZERS true)
+if (NOT CMAKE_SYSTEM_NAME STREQUAL "GNU")
+    set(LWIP_USE_SANITIZERS true)
+endif()
 include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
 
 if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
@@ -45,7 +47,7 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
     target_link_libraries(lwip_unittests ${LIBSUBUNIT})
 endif()
 
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "GNU")
     find_library(LIBUTIL util)
     find_library(LIBPTHREAD pthread)
     find_library(LIBRT rt)

+ 27 - 5
contrib/ports/unix/port/sys_arch.c

@@ -68,6 +68,9 @@
 #include "lwip/stats.h"
 #include "lwip/tcpip.h"
 
+/* Return code for an interrupted timed wait */
+#define SYS_ARCH_INTR 0xfffffffeUL
+
 u32_t
 lwip_port_rand(void)
 {
@@ -489,14 +492,20 @@ cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
   struct timespec rtime1, rtime2, ts;
   int ret;
 
-#ifdef __GNU__
+#ifdef LWIP_UNIX_HURD
   #define pthread_cond_wait pthread_hurd_cond_wait_np
   #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
 #endif
 
   if (timeout == 0) {
-    pthread_cond_wait(cond, mutex);
-    return 0;
+    ret = pthread_cond_wait(cond, mutex);
+    return
+#ifdef LWIP_UNIX_HURD
+    /* On the Hurd, ret == 1 means the RPC has been cancelled.
+     * The thread is awakened (not terminated) and execution must continue */
+    ret == 1 ? SYS_ARCH_INTR :
+#endif
+    (u32_t)ret;
   }
 
   /* Get a timestamp and add the timeout value. */
@@ -517,6 +526,12 @@ cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
 #endif
   if (ret == ETIMEDOUT) {
     return SYS_ARCH_TIMEOUT;
+#ifdef LWIP_UNIX_HURD
+    /* On the Hurd, ret == 1 means the RPC has been cancelled.
+     * The thread is awakened (not terminated) and execution must continue */
+  } else if (ret == EINTR) {
+    return SYS_ARCH_INTR;
+#endif
   }
 
   /* Calculate for how long we waited for the cond. */
@@ -546,11 +561,18 @@ sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
       if (time_needed == SYS_ARCH_TIMEOUT) {
         pthread_mutex_unlock(&(sem->mutex));
         return SYS_ARCH_TIMEOUT;
+#ifdef LWIP_UNIX_HURD
+      } else if(time_needed == SYS_ARCH_INTR) {
+        pthread_mutex_unlock(&(sem->mutex));
+        return 0;
+#endif
       }
       /*      pthread_mutex_unlock(&(sem->mutex));
               return time_needed; */
-    } else {
-      cond_wait(&(sem->cond), &(sem->mutex), 0);
+    } else if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
+      /* Some error happened or the thread has been awakened but not by lwip */
+      pthread_mutex_unlock(&(sem->mutex));
+      return 0;
     }
   }
   sem->c--;