Unix Programming - Is this a poll() bug on solaris?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > November 2004 > Is this a poll() bug on solaris?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Is this a poll() bug on solaris?
Harley Wang

2004-11-03, 2:48 am


Hi,

I met a problem when using poll() on solaris 2.8. The scenario is below,

There are two threads A and B in program. Every thread own some file desc
(struct pollfd poll_info[]) need to poll.

Now A is runing into poll() and waiting for any event on those file desc. Note:
Before A runs into poll(), it has reset its poll_info[].events.

At this time, B was signaled from poll(), and handle the event of its own
pollfds. Sometime B need to change A's poll_info[], then send signal to A's
poll_info[] to wake up A.

Then A is wakeup from poll(). But I found the changes did during A is sleeping
is lost. It seems solaris is rewrite A's poll_info[] with the data before A ran
into poll().

I didn't test select(), not sure if select() has same problem.

Is this known bug on solaris? Or this is normal behavior of solaris?

Thanks in advance!
Harley
David Schwartz

2004-11-03, 2:48 am


"Harley Wang" <huawang@lucent.com> wrote in message
news:41888241.90F1FD5C@lucent.com...

> Then A is wakeup from poll(). But I found the changes did during A is
> sleeping
> is lost. It seems solaris is rewrite A's poll_info[] with the data before
> A ran
> into poll().


If it didn't do that, how would you know what events had occured during
your call to 'poll'?!

> Is this known bug on solaris? Or this is normal behavior of solaris?


It's a bug in your code. If thread A calls 'poll' with an array, it is
using that array. That means thread B cannot modify the array at the same
time. The results of your code are undefined because thread B could wind up
modifying the array before, during, or after the call to 'poll'. Any of the
following timings could happen:

1:
A calls poll
A returns from poll
B modifies the returned poll set

2:
A calls poll
B modifies the passed poll set
A returns from poll getting the unmodified poll set

3:
B modifies the poll set
A calls poll with the modified poll set
A returns from poll getting the modified poll set back

4:
A calls poll
B modifies the poll set just as A call poll
Anything at all can be passed or returned to or from poll in this scenario

So, the short answer is that you didn't follow the memory visiblity
rules and have entered the realm of undefined behavior. Shared data must be
protected by locks -- it cannot be modified in one thread while it is run in
another.

You did not *ensure* that B modifies the data *while* A is in the call
to 'poll'. The modification could occur before the call to poll, during the
call to poll, or after the call returns. At least one of these cases is
undefined.

DS


Stefaan A Eeckels

2004-11-03, 7:48 am

On Wed, 03 Nov 2004 15:01:21 +0800
Harley Wang <huawang@lucent.com> wrote:

> I met a problem when using poll() on solaris 2.8. The scenario is below,
>
> There are two threads A and B in program. Every thread own some file
> desc(struct pollfd poll_info[]) need to poll.
>
> Now A is runing into poll() and waiting for any event on those file
> desc. Note: Before A runs into poll(), it has reset its
> poll_info[].events.
>
> At this time, B was signaled from poll(), and handle the event of its
> own pollfds. Sometime B need to change A's poll_info[], then send signal
> to A's poll_info[] to wake up A.


That's not the way to do this - you need a separate data structure for the
purpose, protected by a mutex. Make the change in this structure, then
copy it to the poll_info structure used by the thread (acquire the mutex
before making the copy in thread "A", and before making the changes in
thread "B"; obviously, "A" should release the mutex before entering the
poll() ;-).

> Then A is wakeup from poll(). But I found the changes did during A is
> sleeping is lost. It seems solaris is rewrite A's poll_info[] with the
> data before A ran into poll().


In other words, you made changes to "A"'s poll_info structure in thread
"B", made a copy (or a mental note of the changes :-), compared it against
the contents of the structure after "A" woke up, and found that the
changes were undone?

Or did you simply notice that the changes you made were ineffectual, i.e.
you modified an "events" member and the kernel gloriously ignored you?

If the latter, then it's perfectly normal (you made changes in user space,
so how would you expect them to be effective in the kernel?).

If the former, there is no requirement for poll() to preserve the contents
of the poll_info.events members if they have been changed by another
thread.

Don't forget that you made changes in user space, and that the kernel has
to copy the modified data structures from kernel space back to user space
(it is unlikely that the memory manager would have the ability to map
individual data structures :-).

--
Stefaan
--
"What is stated clearly conceives easily." -- Inspired sales droid
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com