lkml.org 
[lkml]   [1997]   [Jan]   [27]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateMon, 27 Jan 1997 11:00:49 +0200 (EET)
FromLinus Torvalds <>
SubjectRe: Small fixes for 2.1.23

On Sun, 26 Jan 1997, Ion Badulescu wrote:
> 
> Hi everyone,

Hi there,

> The following patch, relative to 2.1.23, corrects the following
> bugs/features:

Ok, the rest of these look ok, but I'm not applying it because of the
"poll" buglet..

> - the binfmt_script bug which prevents killall from working on scripts
> - the softdog bug which prevents a new daemon from opening the device if
>   NO_WAY_OUT is defined and the old daemon is killed (e.g. when changing
>   initlevels)
> - the floppy bug - duplicated MODULE_PARM(floppy, "s") - which prevents
>   floppy.c from compiling
> - updates for drivers/sound/* (select->poll)
> - finally, my own /proc/swaps patch updated for 2.1.23

The select->poll changes make the source compile, but do not actually do
quite the right thing. The poll changes weren't only a matter of naming
changes, but also changed semantics somewhat (I don't do naming changes
just to change names usually: there is a reason why I didn't want
unmodified code to compile - it needs to get subtly fixed first). 

Anyway, I should have made the changes clear in my announcement of 2.1.23,
but I was too lazy. The changes in the poll behaviour can be broken down
into four different sub-areas:

 - name change: "select" -> "poll" on the VFS layer
 - argument change: only "struct file *" and "poll_table *"
 - return change: instead of returning 0/1, it returns a bitmask of POLL
   events. The old select code was called three times (once for SEL_IN,
   once for SEL_OUT and finally once for SEL_EX), while poll() is called
   just once, and returns a bitmask of all active events.
 - calling change: we don't call the function twice (like we used to),
   instead the function is supposed to add the wait entry to the
   poll_table _first_ before doing the tests (so that any change in state
   will wake up up correctly without any races - calling the function
   twice used to do that for us, but was inefficient) 

The changes can best be explained by showing a trivial example of a
select function that got changed:

	static int aux_select(struct inode *inode, struct file *file,
		int sel_type, select_table * wait)
	{
	        if (sel_type != SEL_IN)
	                return 0;
	        if (aux_ready)
	                return 1;
	        select_wait(&queue->proc_list, wait);
	        return 0;
	}
the above got changed to:

	static unsigned int aux_poll(struct file *file,
		poll_table * wait)
	{
	        poll_wait(&queue->proc_list, wait); 
	        if (aux_ready)
	                return POLLIN | POLLRDNORM;
	        return 0;
	}
Note the differences: calling arguments changed, but most notably the
return values changed. Also, the select_wait() _used_ to be last (and only
done if we return zero), but in the poll version it is done first and done
regardless of what we return (that avoids a race condition - the way linux
does wakeups is so subtle to be almost impossible to explain without a
whiteboard. Very clever, but subtle).

The above is just a trivial example, and it gets a bit more complex when
the old select code used to check for all of SEL_IN/SEL_OUT/SEL_EX
(because then the return bitmask becomes more complex to calculate), but
it shows the most important changes..

		Linus


\
 
 \ /
  Last update: 2005-03-22 12:38    [W:0.233 / U:0.310 seconds]
©2003-2008 Jasper Spaans