Am Donnerstag, den 07.08.2008, 23:05 +0200 schrieb Jörg F. Wittenberger:
> Hi all,
> 
> this is once again a slightly complicated test case.  Again I understand
> all calls for a simpler version.  Just I have a hard time to find one.

I've been able to track this one down to chicken not handling bad
filedescriptors in ##sys#unblock-threads-for-i/o .

The attached patch uses fstat(2) to check the fd-list.

Unfortunately I have no idea how well this is going to be supported
under windows.

Maybe some other detection should be used?

Moreover please review my coding style: I'm rather new in this
environment.

best regards

/Jörg
Index: scheduler.scm
===================================================================
--- scheduler.scm	(Revision 11597)
+++ scheduler.scm	(Arbeitskopie)
@@ -60,6 +60,7 @@
 # include <sys/types.h>
 # include <sys/time.h>
 # include <time.h>
+# include <sys/stat.h>
 static C_word C_msleep(C_word ms);
 C_word C_msleep(C_word ms) {
 #ifdef __CYGWIN__
@@ -341,6 +342,25 @@
   (##sys#setislot t 13 #f)
   (##sys#setslot t 11 (cons fd i/o)) )
 
+(define-foreign-variable error-bad-file int "(errno == EBADF)")
+
+(define (handle-bad-fd! e)
+  (let ((bad ((foreign-lambda*
+	       bool ((integer fd))
+	       "struct stat buf;"
+	       "int i = ( (fstat(fd, &buf) == -1 && errno == EBADF) ? 1 : 0);"
+	       "return(i);")
+	      (car e))))
+    (if (and bad (pair? (cdr e)))
+	(thread-signal!
+	 (cadr c)
+	 (##sys#make-structure
+	  'condition
+	  '(exn i/o) ;; better? '(exn i/o net)
+	  (list '(exn . message) "bad file descriptor"
+		'(exn . arguments) (car e)) )))
+    bad))
+
 (define (##sys#unblock-threads-for-i/o)
   (dbg "fd-list: " ##sys#fd-list)
   (let* ([to? (pair? ##sys#timeout-list)]
@@ -353,8 +373,20 @@
 		   (fxmax 0 (- tmo1 now)) )
 		 0) ) ] )		; otherwise immediate timeout.
     (dbg n " fds ready")
-    (cond [(eq? -1 n) 
-	   (##sys#force-primordial)]
+    (cond [(eq? -1 n)
+	   (cond
+	    (error-bad-file
+	     (set! ##sys#fd-list
+		   (let loop ((l ##sys#fd-list))
+		     (cond
+		      ((null? l) l)
+		      ((handle-bad-fd! (car l))
+		       (##sys#fdset-clear (caar l))
+		       (loop (cdr l)))
+		      (else (cons (car l) (loop (cdr l)))))))
+	     (##sys#fdset-restore)
+	     (##sys#unblock-threads-for-i/o))
+	    (else (##sys#force-primordial))) ]
 	  [(fx> n 0)
 	   (set! ##sys#fd-list
 	     (let loop ([n n] [lst ##sys#fd-list])
_______________________________________________
Chicken-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to