protect myself against invalid fd's in readFdArray/writeFdArray
authorClaus Gittinger <cg@exept.de>
Sat, 02 Mar 1996 13:47:37 +0100
changeset 1061 61012b7bed9c
parent 1060 119d45f975e1
child 1062 baa5827a7a40
protect myself against invalid fd's in readFdArray/writeFdArray (lead to endless EBADF-returns from select & therefore looping system)
ProcSched.st
ProcessorScheduler.st
--- a/ProcSched.st	Sat Mar 02 13:44:19 1996 +0100
+++ b/ProcSched.st	Sat Mar 02 13:47:37 1996 +0100
@@ -1752,6 +1752,46 @@
 
 !ProcessorScheduler methodsFor:'waiting'!
 
+removeCorruptedFds
+    "this is sent when select returns an error due to some invalid 
+     fileDescriptor. May happens, if someone does a readWait/writeWait on a 
+     connection, which somehow gets corrupted.
+     Without special care, all following selects would immediately return with 
+     an #EBADF error, leading to high-frequency polling and a locked up system.
+     (you could still fix things by interrupting on the console and fixing the
+      readFdArray/writeFdArray in the debugger)"
+
+    readFdArray keysAndValuesDo:[:idx :fd |
+        |rslt|
+
+        rslt := OperatingSystem
+                    selectOnAnyReadable:(Array with:fd)
+                               writable:nil
+                              exception:nil
+                            withTimeOut:0.
+
+        (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[
+            ('PROCESSOR: remove invalid read fileDescriptor: ' , fd printString) errorPrintNL.
+            readFdArray at:idx put:nil
+        ]
+    ].
+
+    writeFdArray keysAndValuesDo:[:idx :fd |
+        |rslt|
+
+        rslt := OperatingSystem
+                    selectOnAnyReadable:nil
+                               writable:(Array with:fd)
+                              exception:nil
+                            withTimeOut:0.
+
+        (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[
+            ('PROCESSOR: removing invalid write fileDescriptor: ' , fd printString) errorPrintNL.
+            writeFdArray at:idx put:nil
+        ]
+    ].
+!
+
 checkForInputWithTimeout:millis
     "this is called, when there is absolutely nothing to do;
      hard wait for either input to arrive or a timeout to occur."
@@ -1763,7 +1803,16 @@
 			 writable:writeFdArray
 			exception:nil 
 		      withTimeOut:millis.
-    fd notNil ifTrue:[
+
+    fd isNil ifTrue:[
+	(OperatingSystem lastErrorSymbol == #EBADF) ifTrue:[
+
+	    "/ mhmh - one of the fd's given to me is corrupt.
+	    "/ find out which one .... and remove it
+
+	    self removeCorruptedFds
+	]
+    ] ifFalse:[
 	index := readFdArray indexOf:fd.
 	index ~~ 0 ifTrue:[
 	    sema := readSemaphoreArray at:index.
@@ -1927,6 +1976,6 @@
 !ProcessorScheduler class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Attic/ProcSched.st,v 1.70 1996-02-29 02:24:06 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Attic/ProcSched.st,v 1.71 1996-03-02 12:47:37 cg Exp $'
 ! !
 ProcessorScheduler initialize!
--- a/ProcessorScheduler.st	Sat Mar 02 13:44:19 1996 +0100
+++ b/ProcessorScheduler.st	Sat Mar 02 13:47:37 1996 +0100
@@ -1752,6 +1752,46 @@
 
 !ProcessorScheduler methodsFor:'waiting'!
 
+removeCorruptedFds
+    "this is sent when select returns an error due to some invalid 
+     fileDescriptor. May happens, if someone does a readWait/writeWait on a 
+     connection, which somehow gets corrupted.
+     Without special care, all following selects would immediately return with 
+     an #EBADF error, leading to high-frequency polling and a locked up system.
+     (you could still fix things by interrupting on the console and fixing the
+      readFdArray/writeFdArray in the debugger)"
+
+    readFdArray keysAndValuesDo:[:idx :fd |
+        |rslt|
+
+        rslt := OperatingSystem
+                    selectOnAnyReadable:(Array with:fd)
+                               writable:nil
+                              exception:nil
+                            withTimeOut:0.
+
+        (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[
+            ('PROCESSOR: remove invalid read fileDescriptor: ' , fd printString) errorPrintNL.
+            readFdArray at:idx put:nil
+        ]
+    ].
+
+    writeFdArray keysAndValuesDo:[:idx :fd |
+        |rslt|
+
+        rslt := OperatingSystem
+                    selectOnAnyReadable:nil
+                               writable:(Array with:fd)
+                              exception:nil
+                            withTimeOut:0.
+
+        (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[
+            ('PROCESSOR: removing invalid write fileDescriptor: ' , fd printString) errorPrintNL.
+            writeFdArray at:idx put:nil
+        ]
+    ].
+!
+
 checkForInputWithTimeout:millis
     "this is called, when there is absolutely nothing to do;
      hard wait for either input to arrive or a timeout to occur."
@@ -1763,7 +1803,16 @@
 			 writable:writeFdArray
 			exception:nil 
 		      withTimeOut:millis.
-    fd notNil ifTrue:[
+
+    fd isNil ifTrue:[
+	(OperatingSystem lastErrorSymbol == #EBADF) ifTrue:[
+
+	    "/ mhmh - one of the fd's given to me is corrupt.
+	    "/ find out which one .... and remove it
+
+	    self removeCorruptedFds
+	]
+    ] ifFalse:[
 	index := readFdArray indexOf:fd.
 	index ~~ 0 ifTrue:[
 	    sema := readSemaphoreArray at:index.
@@ -1927,6 +1976,6 @@
 !ProcessorScheduler class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.70 1996-02-29 02:24:06 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.71 1996-03-02 12:47:37 cg Exp $'
 ! !
 ProcessorScheduler initialize!