Index: scheduler.scm =================================================================== --- scheduler.scm (Revision 11663) +++ scheduler.scm (Arbeitskopie) @@ -36,7 +36,7 @@ ##sys#update-thread-state-buffer ##sys#restore-thread-state-buffer ##sys#remove-from-ready-queue ##sys#unblock-threads-for-i/o ##sys#force-primordial ##sys#fdset-input-set ##sys#fdset-output-set ##sys#fdset-clear - ##sys#fdset-select-timeout ##sys#fdset-restore + ##sys#fdset-select-timeout ##sys#fdset-restore ##sys#handle-bad-fd! ##sys#clear-i/o-state-for-thread!) (foreign-declare #< # include # include +# include static C_word C_msleep(C_word ms); C_word C_msleep(C_word ms) { #ifdef __CYGWIN__ @@ -341,6 +342,24 @@ (##sys#setislot t 13 #f) (##sys#setslot t 11 (cons fd i/o)) ) +(define-foreign-variable error-bad-file int "(errno == EBADF)") + +(define (##sys#handle-bad-fd! e) + (dbg "check bad" 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 e) (##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 +372,23 @@ (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) + ((##sys#handle-bad-fd! (car l)) + (##sys#fdset-clear (caar l)) + ;; This is supposed to be a rare case, catch + ;; them one by one. + ;; (loop (cdr l)) + (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])