| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  | ! Copyright (C) 2004, 2008 Slava Pestov. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2014-06-26 16:49:48 -04:00
										 |  |  | USING: accessors alien.data assocs bit-arrays fry | 
					
						
							|  |  |  | io.backend.unix io.backend.unix.multiplexers kernel layouts | 
					
						
							|  |  |  | locals math math.order sequences unix.ffi unix.time ;
 | 
					
						
							| 
									
										
										
										
											2008-12-14 21:03:00 -05:00
										 |  |  | IN: io.backend.unix.multiplexers.select | 
					
						
							| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: select-mx < mx read-fdset write-fdset ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Factor's bit-arrays are an array of bytes, OS X expects | 
					
						
							|  |  |  | ! FD_SET to be an array of cells, so we have to account for | 
					
						
							|  |  |  | ! byte order differences on big endian platforms | 
					
						
							|  |  |  | : munge ( i -- i' )
 | 
					
						
							| 
									
										
										
										
											2011-05-19 18:45:39 -04:00
										 |  |  |     little-endian? [ | 
					
						
							| 
									
										
										
										
											2014-06-26 16:49:48 -04:00
										 |  |  |         cell 4 = 0b11000 0b111000 ? bitxor
 | 
					
						
							|  |  |  |     ] unless ; inline
 | 
					
						
							| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : <select-mx> ( -- mx )
 | 
					
						
							|  |  |  |     select-mx new-mx | 
					
						
							|  |  |  |         FD_SETSIZE 8 * <bit-array> >>read-fdset | 
					
						
							|  |  |  |         FD_SETSIZE 8 * <bit-array> >>write-fdset ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : clear-nth ( n seq -- ? )
 | 
					
						
							|  |  |  |     [ nth ] [ [ f ] 2dip set-nth ] 2bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :: check-fd ( fd fdset mx quot -- )
 | 
					
						
							|  |  |  |     fd munge fdset clear-nth [ fd mx quot call ] when ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-fdset ( fds fdset mx quot -- )
 | 
					
						
							|  |  |  |     [ check-fd ] 3curry each ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : init-fdset ( fds fdset -- )
 | 
					
						
							|  |  |  |     '[ t swap munge _ set-nth ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : read-fdset/tasks ( mx -- seq fdset )
 | 
					
						
							|  |  |  |     [ reads>> keys ] [ read-fdset>> ] bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : write-fdset/tasks ( mx -- seq fdset )
 | 
					
						
							|  |  |  |     [ writes>> keys ] [ write-fdset>> ] bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : max-fd ( assoc -- n )
 | 
					
						
							|  |  |  |     dup assoc-empty? [ drop 0 ] [ keys supremum ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : num-fds ( mx -- n )
 | 
					
						
							| 
									
										
										
										
											2009-08-13 20:21:44 -04:00
										 |  |  |     [ reads>> max-fd ] [ writes>> max-fd ] bi max 1 + ;
 | 
					
						
							| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : init-fdsets ( mx -- nfds read write except )
 | 
					
						
							|  |  |  |     [ num-fds ] | 
					
						
							| 
									
										
										
										
											2009-02-06 05:37:28 -05:00
										 |  |  |     [ read-fdset/tasks [ init-fdset ] keep ] | 
					
						
							|  |  |  |     [ write-fdset/tasks [ init-fdset ] keep ] tri
 | 
					
						
							| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  |     f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-19 05:51:47 -05:00
										 |  |  | M:: select-mx wait-for-events ( nanos mx -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  |     mx | 
					
						
							| 
									
										
										
										
											2010-09-16 00:49:01 -04:00
										 |  |  |     [ init-fdsets nanos dup [ 1000 /i make-timeval ] when select multiplexer-error drop ] | 
					
						
							| 
									
										
										
										
											2008-12-11 23:48:19 -05:00
										 |  |  |     [ [ read-fdset/tasks ] keep [ input-available ] check-fdset ] | 
					
						
							|  |  |  |     [ [ write-fdset/tasks ] keep [ output-available ] check-fdset ] | 
					
						
							|  |  |  |     tri ;
 |