Browse Source

* use sem_timedwait for BasicEventWaitFor if available (linux now)

git-svn-id: trunk@8835 -
micha 18 years ago
parent
commit
5f3e2b10e8
1 changed files with 38 additions and 1 deletions
  1. 38 1
      rtl/unix/cthreads.pp

+ 38 - 1
rtl/unix/cthreads.pp

@@ -36,6 +36,10 @@
 {$endif}
 {$endif}
 
+{$ifdef linux}
+{$define has_sem_timedwait}
+{$endif}
+
 unit cthreads;
 interface
 {$S-}
@@ -444,6 +448,22 @@ begin
 {$endif}
 end;
 
+{$if defined(has_sem_timedwait)}
+
+function cSemaphoreTimedWait(const FSem: Pointer; const Timeout: ttimespec): cint;
+var
+  res: cint;
+  err: cint;
+begin
+  repeat
+    res:=sem_timedwait(PSemaphore(FSem), @Timeout);
+    if res=0 then exit(0);
+    err:=fpgetCerrno;
+  until err<>ESysEINTR;
+  result:=err;
+end;
+
+{$endif}
 
 procedure cSemaphorePost(const FSem: Pointer);
 {$if defined(has_sem_init) or defined(has_sem_open)}
@@ -783,7 +803,23 @@ begin
     end
   else
     begin
-      timespec.tv_sec:=0;
+{$ifdef has_sem_timedwait}
+      fpgettimeofday(@timespec,nil);
+      inc(timespec.tv_nsec, (timeout mod 1000) * 1000000);
+      inc(timespec.tv_sec, timeout div 1000);
+      if timespec.tv_nsec > 1000000000 then
+      begin
+        dec(timespec.tv_nsec, 1000000000);
+        inc(timespec.tv_sec);
+      end;
+      nanores := cSemaphoreTimedWait(plocaleventstate(state)^.FSem, timespec);
+      if nanores = 0 then
+        result := wrSignaled
+      else if nanores = ESysETIMEDOUT then
+        result := wrTimeout
+      else
+        result := wrError;
+{$else}
       { 500 miliseconds or less -> wait once for this duration }
       if (timeout <= 500) then
         loopcnt:=1
@@ -853,6 +889,7 @@ begin
           if (result<>wrTimeOut) then
             break;
         end;
+{$endif}
     end;
   
   if (result=wrSignaled) then